[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

puts / print as method not keyword?

zuzu

12/11/2004 8:13:00 PM

so, i'm thinking about language design with a particular interest in
concatinative combinators (postfix notation). you may remember my
questions and wonderful help jim weirich and others gave me some time
ago on the list w/r/t developing a pipes & filters syntax in ruby.

i started to worry that perhaps i was going to distort ruby out of
shape, when the case study i was running in my head seemed to be the
anomaly. most of my "this is weird" thoughts seem to stem from the
design of the Kernel object and subsequently how it is mixed in to the
Object object. (the Kernel object representing the ruby interpreter /
virtual machine itself; though the Object object representing the
rationally pure originator of all other objects supposedly including
the Kernel.)

so here's what i was thinking... quite alot of ruby idioms make use
of object methods to express themselves in a "data.manipulate" or
"data.express" format; that is, something like:

3.times

in a chain of

3.times {puts "thingy!"}

(perhaps others can contribute other examples, or just look them up
in the pickaxe -- thanks dave & andy.) but the Kernel's puts/print
fuction doesn't seem to carry over. it works fine as a global
keyword, but a programmer cannot

"this is a string".puts

and produce the desired result. instead the programmer must

puts "this is a string"

switching from postfix to prefix notation, most likely intuitive
because of experience C-style printf() or C++ style cout (or i suppose
BASIC).



however, i suppose the real answer should be "shut up and code it that
way for yourself then". but i want to throw this out there for
discussion as to why this was implemented in this way to begin with,
as well as gather information from those who know offhand where the
source of this lies in the default object library.

thanks,
-z


22 Answers

Ilmari Heikkinen

12/11/2004 8:23:00 PM

0


On 11.12.2004, at 22:13, zuzu wrote:

> but the Kernel's puts/print
> fuction doesn't seem to carry over. it works fine as a global
> keyword, but a programmer cannot
>
> "this is a string".puts
>
> and produce the desired result. instead the programmer must
>
> puts "this is a string"

As far as I know, it's a matter of

STDOUT.puts(string)

versus

string.puts(STDOUT)

(and then there's Kernel#p, which is an anomaly)



Julius Plenz

12/11/2004 8:36:00 PM

0

* zuzu <sean.zuzu@gmail.com> [2004-12-11]:
> "this is a string".puts

try: "this is a string\n".display

Julius
--
i=0;p"ispp\e[ggk^Zf\23dfRh\16UMNUNZ".unpack("C*").map{|c|(c+i+=1).chr}.join

zuzu

12/11/2004 8:39:00 PM

0

On Sun, 12 Dec 2004 05:23:10 +0900, Ilmari Heikkinen <kig@misfiring.net> wrote:
>
> On 11.12.2004, at 22:13, zuzu wrote:
>
> > but the Kernel's puts/print
> > fuction doesn't seem to carry over. it works fine as a global
> > keyword, but a programmer cannot
> >
> > "this is a string".puts
> >
> > and produce the desired result. instead the programmer must
> >
> > puts "this is a string"
>
> As far as I know, it's a matter of
>
> STDOUT.puts(string)
>
> versus
>
> string.puts(STDOUT)

yes, precisely! :D

see, my concern then is that the "to where?" question becomes much
more obvious in the second, and much more necessary as ruby grows
beyond just a virtual machine running inside a unix environment or as
ruby grows as a networked language. perhaps i don't just want the
default STDOUT but would like to specify tty3 versus tty9 or perhaps
window7 of some screen tty multiplexing session or how emacs manages
buffers, and so on...

oh, also, correct me if i'm wrong, but method/function argument
passing really should only be used for CONSTRAINTS _not_ DATA.

and so i also feel that

string.puts(STDOUT)

or i'm probably thinking more like

string.puts {STDOUT}

much more closely follows the so-called "Principle of Least Surprise".

> (and then there's Kernel#p, which is an anomaly)

due to its debugging intention, no?

peace,
-z

p.s. thanks for replying so quickly.


Carlos

12/11/2004 8:46:00 PM

0

[zuzu <sean.zuzu@gmail.com>, 2004-12-11 21.13 CET]
> but a programmer cannot
>
> "this is a string".puts
>
> and produce the desired result. instead the programmer must
>
> puts "this is a string"
>
> switching from postfix to prefix notation, most likely intuitive
> because of experience C-style printf() or C++ style cout (or i suppose
> BASIC).
>
>
>
> however, i suppose the real answer should be "shut up and code it that
> way for yourself then". but i want to throw this out there for
> discussion as to why this was implemented in this way to begin with,
> as well as gather information from those who know offhand where the
> source of this lies in the default object library.

You have Object#display. But nobody uses it...

$ ri -T display
--------------------------------------------------------- Object#display
obj.display(port=$>) => nil
------------------------------------------------------------------------
Prints _obj_ on the given port (default +$>+). Equivalent to:

def display(port=$>)
port.write self
end

For example:

1.display
"cat".display
[ 4, 5, 6 ].display
puts

_produces:_

1cat456



zuzu

12/11/2004 8:47:00 PM

0

On Sun, 12 Dec 2004 05:37:40 +0900, Julius Plenz <usenet@plenz.com> wrote:
> * zuzu <sean.zuzu@gmail.com> [2004-12-11]:
> > "this is a string".puts
>
> try: "this is a string\n".display

word!!! yes, thank you.

now, why is this? :D
is this simply a matter of existing english documentation to prefer
"puts" or "print" over "display"?
is it that most programmers for better or worse desend from a
C/C++/Java background?


> Julius
> --
> i=0;p"ispp\e[ggk^Zf\23dfRh\16UMNUNZ".unpack("C*").map{|c|(c+i+=1).chr}.join

peace,
-z


zuzu

12/11/2004 8:52:00 PM

0

On Sun, 12 Dec 2004 05:45:37 +0900, Carlos <angus@quovadis.com.ar> wrote:
> [zuzu <sean.zuzu@gmail.com>, 2004-12-11 21.13 CET]
>
>
> > but a programmer cannot
> >
> > "this is a string".puts
> >
> > and produce the desired result. instead the programmer must
> >
> > puts "this is a string"
> >
> > switching from postfix to prefix notation, most likely intuitive
> > because of experience C-style printf() or C++ style cout (or i suppose
> > BASIC).
> >
> >
> >
> > however, i suppose the real answer should be "shut up and code it that
> > way for yourself then". but i want to throw this out there for
> > discussion as to why this was implemented in this way to begin with,
> > as well as gather information from those who know offhand where the
> > source of this lies in the default object library.
>
> You have Object#display. But nobody uses it...

thank you as well, with an even more complete answer.
(maybe someday ri will work by default on osx/darwin.)

from a language design perspective, or perhaps this is a ruby idomatic
/ programmer organization behavior perspective, any clues as to why
nobody uses it?

is it just obscure? not well documented in english (or at all)? just
not the way most programmers think due to their path-dependency (i.e.
first language learned, and all that...)?

peace,
-z

> $ ri -T display
> --------------------------------------------------------- Object#display
> obj.display(port=$>) => nil
> ------------------------------------------------------------------------
> Prints _obj_ on the given port (default +$>+). Equivalent to:
>
> def display(port=$>)
> port.write self
> end
>
> For example:
>
> 1.display
> "cat".display
> [ 4, 5, 6 ].display
> puts
>
> _produces:_
>
> 1cat456
>
>


Brian Schröder

12/11/2004 9:13:00 PM

0

On Sun, 12 Dec 2004 05:52:25 +0900
zuzu <sean.zuzu@gmail.com> wrote:

> On Sun, 12 Dec 2004 05:45:37 +0900, Carlos <angus@quovadis.com.ar> wrote:
> > [zuzu <sean.zuzu@gmail.com>, 2004-12-11 21.13 CET]
> >
> >
> > > but a programmer cannot
> > >
> > > "this is a string".puts
> > >
> > > and produce the desired result. instead the programmer must
> > >
> > > puts "this is a string"
> > >
> > > switching from postfix to prefix notation, most likely intuitive
> > > because of experience C-style printf() or C++ style cout (or i suppose
> > > BASIC).
> > >
> > >
> > >
> > > however, i suppose the real answer should be "shut up and code it that
> > > way for yourself then". but i want to throw this out there for
> > > discussion as to why this was implemented in this way to begin with,
> > > as well as gather information from those who know offhand where the
> > > source of this lies in the default object library.
> >
> > You have Object#display. But nobody uses it...
>
> thank you as well, with an even more complete answer.
> (maybe someday ri will work by default on osx/darwin.)
>
> from a language design perspective, or perhaps this is a ruby idomatic
> / programmer organization behavior perspective, any clues as to why
> nobody uses it?
>
> is it just obscure? not well documented in english (or at all)? just
> not the way most programmers think due to their path-dependency (i.e.
> first language learned, and all that...)?
>
> [snip]

I can only tell from my experience. I never run across this, because I never
searched for it. I wanted to output something, so I searched for print, found
put and was not surprised at all...

So maybe the first languages learned where all very suggestive to me. What made
me enthusiastic about ruby is, that I can simply express myself the way I
expected to express myself. When trying to do logical (prolog) or purely
functional (haskell) programming, I always thought "intriguing idea, but I
can't map my mind to it". In ruby I can mix functional and imperative
programming and hack away - but without me noticing it my mind got/gets
transformed. I think ruby made me a better programmer in lots of ways. Maybe
someday I will even no longer ask the Kernel to display an object, but ask the
object to display itself. Or maybe I won't, because I always thought the other
way round.

Well, this became quite some prosa, but maybe it helps someone or at least
someone can find herself reflected in it.

Regards,

Brian

--
Brian Schröder
http://ruby.brian-sch...



Yukihiro Matsumoto

12/11/2004 9:19:00 PM

0


In message "Re: puts / print as method not keyword?"
on Sun, 12 Dec 2004 05:38:33 +0900, zuzu <sean.zuzu@gmail.com> writes:

|and so i also feel that
|
| string.puts(STDOUT)
|
|or i'm probably thinking more like
|
| string.puts {STDOUT}
|
|much more closely follows the so-called "Principle of Least Surprise".

It is very interesting to see how POLS differ person to person.
That's one of the reasons I discourage use of the word POLS in any
proposal. ;-)

"puts" was taken from UNIX C output function, which takes an output
string as an argument, so that it is more natural (for me at least) to
take functional form. I would be astonished very much when puts takes
output destination as an argument.

"display" was inherited from Smalltalk.

|see, my concern then is that the "to where?" question becomes much
|more obvious in the second, and much more necessary as ruby grows
|beyond just a virtual machine running inside a unix environment or as
|ruby grows as a networked language. perhaps i don't just want the
|default STDOUT but would like to specify tty3 versus tty9 or perhaps
|window7 of some screen tty multiplexing session or how emacs manages
|buffers, and so on...
|
|oh, also, correct me if i'm wrong, but method/function argument
|passing really should only be used for CONSTRAINTS _not_ DATA.

I don't see any obvious reasons behind your opinion. Can you
elaborate?

matz.


Ilmari Heikkinen

12/11/2004 9:23:00 PM

0

la, 2004-12-11 kello 22:38, zuzu kirjoitti:

> perhaps i don't just want the
> default STDOUT but would like to specify tty3 versus tty9 or perhaps
> window7 of some screen tty multiplexing session or how emacs manages
> buffers, and so on...

You would then replace STDOUT with e.g. STDERR, or even
File.open("log","a"){|f| f.puts(string) }

> oh, also, correct me if i'm wrong, but method/function argument
> passing really should only be used for CONSTRAINTS _not_ DATA.

> and so i also feel that
>
> string.puts(STDOUT)
>
> or i'm probably thinking more like
>
> string.puts {STDOUT}
>
> much more closely follows the so-called "Principle of Least Surprise".

string.puts(STDOUT) creates a coupling, the string must call a method of the
given object with itself as the argument. It must know that the object it's
passed responds to #puts. Also, string.puts(STDOUT) modifies its argument
(by printing a new line), which, to me at least, is a big no-no.

STDOUT.puts(string) modifies only STDOUT. It doesn't (shouldn't) magically add
an extra line to the string. And maybe it's better to have all objects respond
to just #to_s instead of #puts, #print and #write.

The postfix notation is tempting though, hmm..
If you look at unix pipes, they use a syntax like:

method | method | method , last method taking care of doing things

The difference to Ruby's method.method.method is that the shell pipes aren't
namespaced to the preceding object. Ie. With shell pipes it'd be quite doable
to except the following to work in every situation:

gets | reverse | puts , because they are in the global namespace. What you pass
through the pipe doesn't change the available methods.

In ruby

gets.reverse.puts
creates a dependency chain.

gets must return something that responds to reverse, and reverse must return
something that responds to puts. Which is bad. So maybe we should emulate
shell pipes in some other way?


def in; yield self; end

string.in{|s| STDOUT.puts(s)}


Works in dataflow-style, too:

string.in{|s| puts s; s}.reverse.in{|s| puts s}

Keeps concerns to the objects whom they may concern (String
doesn't have to know about what methods IO has, etc.), and doesn't do
black-box modifications to its arguments.


Comments?



zuzu

12/11/2004 9:45:00 PM

0

On Sun, 12 Dec 2004 06:18:47 +0900, Yukihiro Matsumoto
<matz@ruby-lang.org> wrote:
>
> In message "Re: puts / print as method not keyword?"
> on Sun, 12 Dec 2004 05:38:33 +0900, zuzu <sean.zuzu@gmail.com> writes:
>
> |and so i also feel that
> |
> | string.puts(STDOUT)
> |
> |or i'm probably thinking more like
> |
> | string.puts {STDOUT}
> |
> |much more closely follows the so-called "Principle of Least Surprise".
>
> It is very interesting to see how POLS differ person to person.
> That's one of the reasons I discourage use of the word POLS in any
> proposal. ;-)

quite true. it's quite subjective.

> "puts" was taken from UNIX C output function, which takes an output
> string as an argument, so that it is more natural (for me at least) to
> take functional form. I would be astonished very much when puts takes
> output destination as an argument.

this makes sense. particularly due, as you say, to experience with unix c.

> "display" was inherited from Smalltalk.

aaaah, very interesting.

> |see, my concern then is that the "to where?" question becomes much
>
>
> |more obvious in the second, and much more necessary as ruby grows
> |beyond just a virtual machine running inside a unix environment or as
> |ruby grows as a networked language. perhaps i don't just want the
> |default STDOUT but would like to specify tty3 versus tty9 or perhaps
> |window7 of some screen tty multiplexing session or how emacs manages
> |buffers, and so on...
> |
> |oh, also, correct me if i'm wrong, but method/function argument
> |passing really should only be used for CONSTRAINTS _not_ DATA.
>
> I don't see any obvious reasons behind your opinion. Can you
> elaborate?
>
> matz.

for the function argument issue... i think the idea of constraints
has its origins in math just as the idea of a function does. however,
i encounter it much more vocally in the study of process in the fields
of systems theory and cybernetics. when utilizing a process model to
solve a problem, a differentiation is made between variables (the
unknowns you seek to know) and constraints (arbitrary filters to limit
the search space).
however, this does become not so obvious in the real world where the
data output from one function can define the constraints input into
another function. but in many dataflow languages, and i think even in
the useful difference between closures and function arguments, a
distinction is made between the dataflow and "defining the filters"
(constraints).

as for the issue of defining what STDOUT is set to... this seems
"obvious" to me because of the dataflow involved, moving a stream
linearly from inputs to outputs. usually a screen or printer to
teletype or such is the "final" output / destination, or at least
represents the intersection where that stream of information is then
input into a human and an "input device" such as a keyboard or mouse
receives human output back into the computer -- so thus a cycle of
human-computer interaction persists with the human as just another
filter/generator.

i hope i explained this well. i will be happy to elaborate futher.
-z