[Pharo-users] Smalltalk Quine

Sven Van Caekenberghe sven at beta9.be
Tue Jul 17 13:03:52 EDT 2012


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








More information about the Pharo-users mailing list