Smalltalk Quine

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Smalltalk Quine

Sven Van Caekenberghe
By accident I visited the following website today

        http://igoro.com/archive/how-to-write-a-self-printing-program/

It is about writing a self-printing program, also known as a quine

        http://en.wikipedia.org/wiki/Quine_(computing)

This has probably been done before, but I had to try to do it in Pharo Smalltalk.
Paste the following in a Workspace and either print or inspect it.

String streamContents: [ :stream | | lines |
        lines := #(
                'String streamContents: [ :stream | | lines |'
                ' lines := #('
                ' ).'
                ' stream'
                ' << ''String streamContents: [ :stream | | lines |''; cr;'
                ' tab; << ''lines := #(''; cr.'
                ' lines do: [ :each | stream tab; tab; print: each; cr ].'
                ' stream tab; << '').''; cr.'
                ' (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
                ' stream tab; << '']''; cr.'
        ).
        stream
                << 'String streamContents: [ :stream | | lines |'; cr;
                tab; << 'lines := #('; cr.
        lines do: [ :each | stream tab; tab; print: each; cr ].
        stream tab; << ').'; cr.
        (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
        stream tab; << ']'; cr.
        ]

The result _is_ the same, but it is a bit hard to see because String>>#printString renders the printed representation (doubling quotes). To check you can inspect the string and print it on the transcript (after opening it)

        Transcript show: self

or you can ask the compiler for help

        Compiler evaluate: self readStream

if you inspect the result of the above expression, you can keep on doing this forever.

It is also pretty easy to extend the example with your own code.

String streamContents: [ :stream | | lines |
        lines := #(
                'String streamContents: [ :stream | | lines |'
                ' lines := #('
                ' ).'
                ' stream'
                ' << ''String streamContents: [ :stream | | lines |''; cr;'
                ' tab; << ''lines := #(''; cr.'
                ' lines do: [ :each | stream tab; tab; print: each; cr ].'
                ' stream tab; << '').''; cr.'
                ' (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
                ' stream tab; << '']''; cr.'
                ' self inform: ''Cool, no ?'''
        ).
        stream
                << 'String streamContents: [ :stream | | lines |'; cr;
                tab; << 'lines := #('; cr.
        lines do: [ :each | stream tab; tab; print: each; cr ].
        stream tab; << ').'; cr.
        (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
        stream tab; << ']'; cr.
        self inform: 'Cool, no ?'
        ]

Just add the extra code twice.

Enjoy!

Sven


--
Sven Van Caekenberghe
http://stfx.eu
Smalltalk is the Red Pill





Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk Quine

Sven Van Caekenberghe
Now that I actually read the Wikipedia article, I made the code smaller and more elegant ;-)

String streamContents: [ :stream | | lines |
        lines := #(
                'String streamContents: [ :stream | | lines |'
                ' lines := #('
                ' ).'
                ' (lines first: 2) do: [ :each | stream << each; cr ].'
                ' lines do: [ :each | stream tab: 2; print: each; cr ].'
                ' (lines allButFirst: 2) do: [ :each | stream << each; cr ].'
                ' stream nextPut: $]; cr.'
        ).
        (lines first: 2) do: [ :each | stream << each; cr ].
        lines do: [ :each | stream tab: 2; print: each; cr ].
        (lines allButFirst: 2) do: [ :each | stream << each; cr ].
        stream nextPut: $]; cr.
]

On 17 Jul 2012, at 19:03, Sven Van Caekenberghe wrote:

> By accident I visited the following website today
>
> http://igoro.com/archive/how-to-write-a-self-printing-program/
>
> It is about writing a self-printing program, also known as a quine
>
> http://en.wikipedia.org/wiki/Quine_(computing)
>
> This has probably been done before, but I had to try to do it in Pharo Smalltalk.
> Paste the following in a Workspace and either print or inspect it.
>
> String streamContents: [ :stream | | lines |
> lines := #(
> 'String streamContents: [ :stream | | lines |'
> ' lines := #('
> ' ).'
> ' stream'
> ' << ''String streamContents: [ :stream | | lines |''; cr;'
> ' tab; << ''lines := #(''; cr.'
> ' lines do: [ :each | stream tab; tab; print: each; cr ].'
> ' stream tab; << '').''; cr.'
> ' (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
> ' stream tab; << '']''; cr.'
> ).
> stream
> << 'String streamContents: [ :stream | | lines |'; cr;
> tab; << 'lines := #('; cr.
> lines do: [ :each | stream tab; tab; print: each; cr ].
> stream tab; << ').'; cr.
> (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
> stream tab; << ']'; cr.
> ]
>
> The result _is_ the same, but it is a bit hard to see because String>>#printString renders the printed representation (doubling quotes). To check you can inspect the string and print it on the transcript (after opening it)
>
> Transcript show: self
>
> or you can ask the compiler for help
>
> Compiler evaluate: self readStream
>
> if you inspect the result of the above expression, you can keep on doing this forever.
>
> It is also pretty easy to extend the example with your own code.
>
> String streamContents: [ :stream | | lines |
> lines := #(
> 'String streamContents: [ :stream | | lines |'
> ' lines := #('
> ' ).'
> ' stream'
> ' << ''String streamContents: [ :stream | | lines |''; cr;'
> ' tab; << ''lines := #(''; cr.'
> ' lines do: [ :each | stream tab; tab; print: each; cr ].'
> ' stream tab; << '').''; cr.'
> ' (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
> ' stream tab; << '']''; cr.'
> ' self inform: ''Cool, no ?'''
> ).
> stream
> << 'String streamContents: [ :stream | | lines |'; cr;
> tab; << 'lines := #('; cr.
> lines do: [ :each | stream tab; tab; print: each; cr ].
> stream tab; << ').'; cr.
> (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
> stream tab; << ']'; cr.
> self inform: 'Cool, no ?'
> ]
>
> Just add the extra code twice.
>
> Enjoy!
>
> Sven
>
>
> --
> Sven Van Caekenberghe
> http://stfx.eu
> Smalltalk is the Red Pill
>
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk Quine

Bernat Romagosa
Cool one! A much shorter "famous" quine in Smalltalk is:

[ :s | Transcript show: s; show: s printString ] value: '[ :s | Transcript show: s; show: s printString ] value: '

Cheers,

2012/7/17 Sven Van Caekenberghe <[hidden email]>
Now that I actually read the Wikipedia article, I made the code smaller and more elegant ;-)

String streamContents: [ :stream | | lines |
        lines := #(
                'String streamContents: [ :stream | | lines |'
                '       lines := #('
                '       ).'
                '       (lines first: 2) do: [ :each | stream << each; cr ].'
                '       lines do: [ :each | stream tab: 2; print: each; cr ].'
                '       (lines allButFirst: 2) do: [ :each | stream << each; cr ].'
                '       stream nextPut: $]; cr.'
        ).
        (lines first: 2) do: [ :each | stream << each; cr ].
        lines do: [ :each | stream tab: 2; print: each; cr ].
        (lines allButFirst: 2) do: [ :each | stream << each; cr ].
        stream nextPut: $]; cr.
]

On 17 Jul 2012, at 19:03, Sven Van Caekenberghe wrote:

> By accident I visited the following website today
>
>       http://igoro.com/archive/how-to-write-a-self-printing-program/
>
> It is about writing a self-printing program, also known as a quine
>
>       http://en.wikipedia.org/wiki/Quine_(computing)
>
> This has probably been done before, but I had to try to do it in Pharo Smalltalk.
> Paste the following in a Workspace and either print or inspect it.
>
> String streamContents: [ :stream | | lines |
>       lines := #(
>               'String streamContents: [ :stream | | lines |'
>               '       lines := #('
>               '       ).'
>               '       stream'
>               '               << ''String streamContents: [ :stream | | lines |''; cr;'
>               '               tab; << ''lines := #(''; cr.'
>               '       lines do: [ :each | stream tab; tab; print: each; cr ].'
>               '       stream tab; << '').''; cr.'
>               '       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
>               '       stream tab; << '']''; cr.'
>       ).
>       stream
>               << 'String streamContents: [ :stream | | lines |'; cr;
>               tab; << 'lines := #('; cr.
>       lines do: [ :each | stream tab; tab; print: each; cr ].
>       stream tab; << ').'; cr.
>       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
>       stream tab; << ']'; cr.
>       ]
>
> The result _is_ the same, but it is a bit hard to see because String>>#printString renders the printed representation (doubling quotes). To check you can inspect the string and print it on the transcript (after opening it)
>
>       Transcript show: self
>
> or you can ask the compiler for help
>
>       Compiler evaluate: self readStream
>
> if you inspect the result of the above expression, you can keep on doing this forever.
>
> It is also pretty easy to extend the example with your own code.
>
> String streamContents: [ :stream | | lines |
>       lines := #(
>               'String streamContents: [ :stream | | lines |'
>               '       lines := #('
>               '       ).'
>               '       stream'
>               '               << ''String streamContents: [ :stream | | lines |''; cr;'
>               '               tab; << ''lines := #(''; cr.'
>               '       lines do: [ :each | stream tab; tab; print: each; cr ].'
>               '       stream tab; << '').''; cr.'
>               '       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
>               '       stream tab; << '']''; cr.'
>               '       self inform: ''Cool, no ?'''
>       ).
>       stream
>               << 'String streamContents: [ :stream | | lines |'; cr;
>               tab; << 'lines := #('; cr.
>       lines do: [ :each | stream tab; tab; print: each; cr ].
>       stream tab; << ').'; cr.
>       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
>       stream tab; << ']'; cr.
>       self inform: 'Cool, no ?'
>       ]
>
> Just add the extra code twice.
>
> Enjoy!
>
> Sven
>
>
> --
> Sven Van Caekenberghe
> http://stfx.eu
> Smalltalk is the Red Pill
>
>
>
>
>





--
Bernat Romagosa.
Reply | Threaded
Open this post in threaded view
|

Re: Smalltalk Quine

Sven Van Caekenberghe

On 18 Jul 2012, at 09:24, Bernat Romagosa wrote:

> Cool one! A much shorter "famous" quine in Smalltalk is:
>
> [ :s | Transcript show: s; show: s printString ] value: '[ :s | Transcript show: s; show: s printString ] value: '

Aah, that one is so much better, really.

I suspected there would be other, but I never saw them.

Thanks!

> 2012/7/17 Sven Van Caekenberghe <[hidden email]>
> Now that I actually read the Wikipedia article, I made the code smaller and more elegant ;-)
>
> String streamContents: [ :stream | | lines |
>         lines := #(
>                 'String streamContents: [ :stream | | lines |'
>                 '       lines := #('
>                 '       ).'
>                 '       (lines first: 2) do: [ :each | stream << each; cr ].'
>                 '       lines do: [ :each | stream tab: 2; print: each; cr ].'
>                 '       (lines allButFirst: 2) do: [ :each | stream << each; cr ].'
>                 '       stream nextPut: $]; cr.'
>         ).
>         (lines first: 2) do: [ :each | stream << each; cr ].
>         lines do: [ :each | stream tab: 2; print: each; cr ].
>         (lines allButFirst: 2) do: [ :each | stream << each; cr ].
>         stream nextPut: $]; cr.
> ]
>
> On 17 Jul 2012, at 19:03, Sven Van Caekenberghe wrote:
>
> > By accident I visited the following website today
> >
> >       http://igoro.com/archive/how-to-write-a-self-printing-program/
> >
> > It is about writing a self-printing program, also known as a quine
> >
> >       http://en.wikipedia.org/wiki/Quine_(computing)
> >
> > This has probably been done before, but I had to try to do it in Pharo Smalltalk.
> > Paste the following in a Workspace and either print or inspect it.
> >
> > String streamContents: [ :stream | | lines |
> >       lines := #(
> >               'String streamContents: [ :stream | | lines |'
> >               '       lines := #('
> >               '       ).'
> >               '       stream'
> >               '               << ''String streamContents: [ :stream | | lines |''; cr;'
> >               '               tab; << ''lines := #(''; cr.'
> >               '       lines do: [ :each | stream tab; tab; print: each; cr ].'
> >               '       stream tab; << '').''; cr.'
> >               '       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
> >               '       stream tab; << '']''; cr.'
> >       ).
> >       stream
> >               << 'String streamContents: [ :stream | | lines |'; cr;
> >               tab; << 'lines := #('; cr.
> >       lines do: [ :each | stream tab; tab; print: each; cr ].
> >       stream tab; << ').'; cr.
> >       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
> >       stream tab; << ']'; cr.
> >       ]
> >
> > The result _is_ the same, but it is a bit hard to see because String>>#printString renders the printed representation (doubling quotes). To check you can inspect the string and print it on the transcript (after opening it)
> >
> >       Transcript show: self
> >
> > or you can ask the compiler for help
> >
> >       Compiler evaluate: self readStream
> >
> > if you inspect the result of the above expression, you can keep on doing this forever.
> >
> > It is also pretty easy to extend the example with your own code.
> >
> > String streamContents: [ :stream | | lines |
> >       lines := #(
> >               'String streamContents: [ :stream | | lines |'
> >               '       lines := #('
> >               '       ).'
> >               '       stream'
> >               '               << ''String streamContents: [ :stream | | lines |''; cr;'
> >               '               tab; << ''lines := #(''; cr.'
> >               '       lines do: [ :each | stream tab; tab; print: each; cr ].'
> >               '       stream tab; << '').''; cr.'
> >               '       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].'
> >               '       stream tab; << '']''; cr.'
> >               '       self inform: ''Cool, no ?'''
> >       ).
> >       stream
> >               << 'String streamContents: [ :stream | | lines |'; cr;
> >               tab; << 'lines := #('; cr.
> >       lines do: [ :each | stream tab; tab; print: each; cr ].
> >       stream tab; << ').'; cr.
> >       (lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
> >       stream tab; << ']'; cr.
> >       self inform: 'Cool, no ?'
> >       ]
> >
> > Just add the extra code twice.
> >
> > Enjoy!
> >
> > Sven
> >
> >
> > --
> > Sven Van Caekenberghe
> > http://stfx.eu
> > Smalltalk is the Red Pill
> >
> >
> >
> >
> >
>
>
>
>
>
> --
> Bernat Romagosa.