Why I don't use Ruby.

L

Lennon Day-Reynolds

Forgot to copy the list on this...sorry to anyone who was hoping this
thread would just die.

---------- Forwarded message ----------

Lothar,

Thanks for "weighing in." You're definitely right about many of the
corrections, but I also think there are a few places where we're just
getting mixed up on terminology (probably due to my admittedly
"amateur" knowledge of programming language implementation).

Hello Lennon, [...]
Sorry but here you miss the point, using file handles, DLL's and
native structure does not mean anything for implementing an image
based language (it's not a heap image by the way).

I'm confused that on the one hand, you would say that native libraries
and data structures are not the problem, and on the other that the
mixing of Ruby and C stack preclude serialization. I think of the two
as more or less equivalent -- use native structures and calling
conventions, and you're tied to that execution model.

(BTW, what is the correct term for the dumped image? "Heap image" was
the standard term used within the language implementation group I
worked for a few years ago, who included old Lucid Lisp core
developers, but it's possible I'm mis-using it.)

[...]
At the moment you can't dump methods and classes. So this would
require a lot of work. We are not talking about data persistence here.

Sorry, I'm thinking in terms of Lisp, where code simply *is* a
special-case type of data. I'm curious as to what about the internal
representation of Ruby code objects is imcompatible with normal data
serialization methods -- is it just that the code isn't constructed in
a relocatable way?

[...]
The current problem is the serialization of the program stack because
there native C function calls and ruby calls are mixed. Okay we could
dump only if there is nothing on the stack (which is the case when the
program exits normally), and return to a special "main" function on
the next start, but this is normally not that what you want in an
image based language.

See my contents above for my confusion on this point. I don't disagree
that freely mixing the Ruby and C stacks causes problems for global
persistence, but I do wonder how continuations are implemented in that
case. Are they just using setjmp/longjmp?

Again, my experience with Common Lisp and Scheme colored my
interpretation here; when generating an image, you actually *did*
specify a toplevel function to enter at start, though most had a
default setting of the REPL mainloop.

[...]
I think the technical implementation is not the difficult thing here,
its the current state of libraries.

That's always the critical issue with major language implementation
changes; if you core API compatibility, you effectively create a new
language from the perspective of library authors.
Oh yes, i implemented an LISP system in about 50000 lines of Assembler
code many many years ago. The core system, the VM, is not difficult to
write, but we would need a complete rewrite of Ruby.

I'm sorry; perhaps I got carried away in my earlier comments about the
amount of work involved in adding image-based persistence to the
existing Ruby runtime. I was thinking more of the overall object
model, not the nitty-gritty details of maintaining low-level
compatibility.

It doesn't seem quite as bleak as "needing a complete rewrite,"
though. There's even a precedent in "that other language". (i.e., the
Python core developers seperated the Python and C stacks so they could
implement generators).

Thanks for the additional information,

Lennon
 
L

Lennon Day-Reynolds

Doh! Should have checked the source...I could have answered one of my
own questions:

Q: Do continuations use setjmp/longjmp?
A: No, they use threads. But threads use setjmp/longjmp.

Lennon
 
R

Rando Christensen

Perhaps because we would like to see more people using Ruby? Or even
just because the sort of people who use "fringe" languages like Ruby
tend to enjoy discussion of obscure details of implementation and
semantics?

That's certainly the only reason I'm on the ruby lists. I haven't had a
chance to write any serious ruby code in a year and a half, but since I
love programming so much, and especially in ruby, the mailing lists of
a young language such as ruby provide insightful looks into the heart
of what coding really is.

That or I'm just a huge nerd.
 
T

TLOlczyk

I'm not sure what you mean here. Do you want to freeze the interpreter
in a given state? Or do you feel the need for some serialization
format that can be retrieved at any time fast? (in this case Marshal
could fit, maybe?)
Sigh. The way things are going today, I've finally gotten to Usenet
today, but on the radio is a very good discussion of the American
Revolution. So I can't pay attention to the whole thread, but
I will discuss this part.

Let us as an example look at a program that looks at a directory of
Web pages, and traces through them. If it cannot find a link to a
certain page, then it creates a link on a page in a prescribed manner.

You've written the program and tested it on a small data set.
Now you want to test it on a large data set. It fails miserably
and you try to debug.
Phase one of the program gets a list of all the files in the directory
( recursively ).
Phase two is to scan the root files for hrefs. Then scan the files in
the hrefs. Then ... untill there are no more files to scan.
Phase three is to pick some file you didn't reach and create a link to
it.

So you work on Phase one and get it to run.
Then you work on Phase two. But it takes Phase one
ten minutes to run. So each time you test a fix in phase two
it takes at least ten minutes to run.

So you save an image at the end of phase one. Each time
you test phase two, you load the image from phase one
and just test phase two. Save ten minutes on each test run.


The reply-to email address is (e-mail address removed).
This is an address I ignore.
To reply via email, remove 2002 and change yahoo to
interaccess,

**
Thaddeus L. Olczyk, PhD

There is a difference between
*thinking* you know something,
and *knowing* you know something.
 
B

Bill Kelly

From: "TLOlczyk said:
Let us as an example look at a program that looks at a directory of
Web pages, and traces through them. If it cannot find a link to a
certain page, then it creates a link on a page in a prescribed manner.

You've written the program and tested it on a small data set.
Now you want to test it on a large data set. It fails miserably
and you try to debug.
Phase one of the program gets a list of all the files in the directory
( recursively ).
Phase two is to scan the root files for hrefs. Then scan the files in
the hrefs. Then ... untill there are no more files to scan.
Phase three is to pick some file you didn't reach and create a link to
it.

So you work on Phase one and get it to run.
Then you work on Phase two. But it takes Phase one
ten minutes to run. So each time you test a fix in phase two
it takes at least ten minutes to run.

Although different than saving the whole program image,
It's pretty to load/save entire object hierarchies in
Ruby... For ex:

# A little boilerplate...

require 'yaml/store'
ystore = YAML::Store.new("my_persistent_data")

# At the end of phase one, we'll have our file list,
# which we can persist as easily as:

ystore.transaction { ystore["filelist"] = phase_one_filelist }

# At the beginning of phase two, we can load it:

phase_one_filelist = ystore.transaction { ystore["filelist"] }


. . This would allow phase 1 and 2 to be totally separate
ruby programs, if you like.

Just one possibility...


Regards,

Bill
 
A

Austin Ziegler

You've written the program and tested it on a small data set.
Now you want to test it on a large data set. It fails miserably
and you try to debug.
Phase one of the program gets a list of all the files in the directory
( recursively ).
Phase two is to scan the root files for hrefs. Then scan the files in
the hrefs. Then ... untill there are no more files to scan.
Phase three is to pick some file you didn't reach and create a link to
it.

So you work on Phase one and get it to run.
Then you work on Phase two. But it takes Phase one
ten minutes to run. So each time you test a fix in phase two
it takes at least ten minutes to run.

So you save an image at the end of phase one. Each time
you test phase two, you load the image from phase one
and just test phase two. Save ten minutes on each test run.

There is no reason that you can't do this with Ruby. If I have code
that works like:

file_list = find_files
missing_files = file_list - find_hrefs(file_list)
make_hrefs(missing_files)

Then I can simply do:

file_list = find_files
File.open("file_list.m", "wb") { |f| f.write Marshal.dump(file_list) }

Then, I can make the main loop do:

file_list = Marshal.load(File.read("file_list.m"))
missing_files = file_list - find_hrefs(find_files)
make_hrefs(missing_files)

With a bit of work, you could integrate this into the main program; it
might even be desirable if find_hrefs takes even longer than
find_files; that way, you could choose to load a predetermined
file_list (making it possible to "version" such lists) or use the
stored file_list as a comparison point. Or, even, do something like:

if File.exists?("file_list.m")
file_list = Marshal.load(File.read("file_list.m"))
File.rm("missing_files.rm")
else
file_list = find_files
end

begin
if File.exists?("missing_files.m")
missing_files = Marshal.load(File.read("missing_files.m")
File.rm("missing_files.rm")
else
missing_files = file_list - find_hrefs(find_files)
end
rescue
File.open("file_list.m", "wb") { |f| f.write Marshal.dump(file_list) }
raise
end

begin
make_hrefs(missing_files)
rescue
File.open("missing_files.m", "wb") { |f| f.write Marshal.dump(file_list) }
raise
end

Now, you have something repeatable that withstands all sorts of errors
without having to repeat portions that you don't need to do.

-austin
 
N

Nicholas Van Weerdenburg

--------------030405050000010400020005
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Personally, I think languages are about the right tool for the job, and
Perl, Python and Ruby have nicely proven that dynamic file-based
scripting languages are more then sufficient for a huge variety of
programming tasks. If you are looking for a secondary tool-language, I
can't imagine images, native compilers, and REPL being so critical as to
drop Ruby. What better options are there? And the points about native
compilers in the responses are well put- it's a trade off, and in the
Ruby world you can drop into C where you need to (not ideal, but
sufficient). As Donald Knuth put it, "premature optimization is the root
of all evil".

A question back to the original poster: I think that many Rubyists and
Pythonists return to native compiled languages etc. only to drop them
because the loss of productivity is too painful and costly. What effects
do the problem domains you code in have on this tradeoff, and what
solutions have you found?

Images would be nice, but the scale of most Ruby programs I write, and
the methods that I write them by, don't make me lament them too much.
One epiphany test driven development has produced in programmers is that
tests drive the design, forcing good design early and often- e.g. the
common statement that TDD isn't really about testing.

The reason for this is that unit testability requires clean interfaces,
strong cohesion, loose coupling- i.e. good modular code. Constantly
subjecting code to testing from the start forces continual design
decisions and refactoring to maintain testability, and the modularity is
easier to maintain as a result.

If your code requires 10 minutes to get to a certain point, and you
can't easily capture that state with a data-only dump (e.g. Marshal or
YAML), and then continue testing from that point, that would be a good
motivation to refactor. However, if TDD hasn't been followed up to that
point, the code may be hard to seperate due to the design debt built up
by not having the code constantly challenged by small tests (my solution
there is to use log4x to due a pseudo-design-by-contract, make core
domain classes invariant, elimate trival singletons/globals, and then
find a couple of good "cut" points to get pseudo-modularity, and then
try to use TDD going forward).

(Aside: Personally, I learned more about design and design patterns via
TDD and refactoring in six months then I did in 5 years of pattern
reading. In my real world career, the problems and problem domains I
coded tended to preclude writing the same program multiple times and
personally trying various design approaches. And the nature of
traditional coding practice is that the early design decisions tend to
stick. So most projects get stuck with marginal designs. The nature of
TDD/refactoring and there emergent design practices is that you get to
see broken/fixed design elements continually in the same coding process,
and the more elegant and robust end product result in a much more
learning intense experience).

I guess the short summary to my long-winded point is that unit-tests and
TDD somewhat obviate the need for images from a development process, and
I think other responses indicated that REPL is well handled in Ruby and
that the speed issue is well enough handled by using C to provide point
optimization where necessary (in clear recognization that certain
problems and problem domains would find this insufficient).

Regards.
Nick
Sigh. The way things are going today, I've finally gotten to Usenet
today, but on the radio is a very good discussion of the American
Revolution. So I can't pay attention to the whole thread, but
I will discuss this part.

Let us as an example look at a program that looks at a directory of
Web pages, and traces through them. If it cannot find a link to a
certain page, then it creates a link on a page in a prescribed manner.

You've written the program and tested it on a small data set.
Now you want to test it on a large data set. It fails miserably
and you try to debug.
Phase one of the program gets a list of all the files in the directory
( recursively ).
Phase two is to scan the root files for hrefs. Then scan the files in
the hrefs. Then ... untill there are no more files to scan.
Phase three is to pick some file you didn't reach and create a link to
it.

So you work on Phase one and get it to run.
Then you work on Phase two. But it takes Phase one
ten minutes to run. So each time you test a fix in phase two
it takes at least ten minutes to run.

So you save an image at the end of phase one. Each time
you test phase two, you load the image from phase one
and just test phase two. Save ten minutes on each test run.


The reply-to email address is (e-mail address removed).
This is an address I ignore.
To reply via email, remove 2002 and change yahoo to
interaccess,

**
Thaddeus L. Olczyk, PhD

There is a difference between
*thinking* you know something,
and *knowing* you know something.

--------------030405050000010400020005--
 
N

Nicholas Van Weerdenburg

If Ruby is 2-6X more productive then Java, wouldn't it make sense for
almost all software projects to use full lifecycle prototypes? That is,
everything is built in Ruby, completely, and this forms a key part of
the specification and requirements feedback for the lagging J2EE /etc.
commerical implementation? Are there any cases of this being attempted
and are there industry learning/best practices in this regard?

Nick
 
N

Nicholas Van Weerdenburg

I get the impression that the J2EE world is starting to go ballastic
over Jython. JRuby gets some mention, but not that much, and I get the
impression that the long term prospects of JRuby are a bit mixed. For
this reason, I felt compelled to learn some Jython so I could use a
modern language in my day-to-day J2EE work.

Unfortunatly, I really can't stand using Python. The selfs, method
__protection__ mechanism, and lack of expression-orientation (unlike
Lisp and Ruby) make me weep. I'm still plinking at it here and there,
giving it a chance, but my mindset is not improving, and I'm starting to
think Python claims of readability are only relative to Perl- I find
Java/C/C++ easier to read. But that's really irrelevant to this point,
outside of my personal motivation for looking at JRuby more seriously.

So now I'm trying to use JRuby, and it's much better then I expected.
However, I'm still concerned about:
1. it's robustness and how it impacts my chosing to use it, and
2. it's impact on Ruby longterm due to prevalence of Jython. I get the
impression that Jython is becoming almost the defacto J2EE scripting
language, with Groovy possibly taking off when it's more mature (is it
just me, or does Groovy look a lot like a Ruby clone with a bit of Java
baggage left in for more seamless interoperability?). Where Jython has
followed Python into general usage, that could change with Jython being
the reason people use Python.

Not sure what point is...I guess I'm looking for some
experiences/ideas/feedback. I think dynamic JVM langauges are going to
become an essential part of enterprise Java, and I'm hoping I don't have
to use Jython on my next job. Those underscores and selfs- how can
anyone stand it? And the lack of expression-kindness.

Thanks,
Nick
 
D

David Garamond

Lennon said:
Perhaps because we would like to see more people using Ruby? Or even
just because the sort of people who use "fringe" languages like Ruby
tend to enjoy discussion of obscure details of implementation and
semantics?

As much as we like that to happen, Ruby is not for everyone.

+ it has many Perlisms (not that it's bad) that many people can't bear.

+ it's purely object-oriented (unlike Python & Perl), thus functional or
procedural guys might get offended or turned off.

+ it comes from Japan.

I am guessing that Python will always be more popular than Ruby in
general, because the language is more acceptable to many people.
However, that's fine. I myself think that the Ruby language is perfect
for me. It has the nice balance of practicality and purity. It has a
nice syntax. It is pretty popular (unlike, say, Ocaml or Haskell) so
it's easier to find libraries or bindings for many things. It simply rocks.
 
J

James Britt

David said:
As much as we like that to happen, Ruby is not for everyone.

...
+ it's purely object-oriented (unlike Python & Perl), thus functional or
procedural guys might get offended or turned off.

Um, I don't see this as true. Certainly one can write all the
procedural code one likes in Ruby (I know *I've* managed to do it), and
I believe the same is pretty much true for writing functional code.

The numerous discussions here comparing Python and Ruby suggest that
there is no reason one cannot do functional programming in Ruby at least
to the same degree as one can in Python, if not more so.

There are enough previous ruby-talk threads on Python vs. Ruby, so we
don't need another one. But while there are numerous reasons people may
find Ruby not to their taste, the idea that one is obligated to do OO
programming, or held back from doing non-OO development, isn't one of them.

One of the best things about Ruby is you can use OO modeling to get you
most of the way through a program's design, then switch to functional or
procedural techniques for the last mile.

Or vice versa.

See also:

http://www.ping.de/~flori/ruby/programs/functional.html
http://c2.com/cgi/wiki?FunctionalProgrammingLanguages
http://c2.com/cgi/wiki?PythonVsRuby (look for the discussion on
functional programming)


I am guessing that Python will always be more popular than Ruby in
general, because the language is more acceptable to many people.

That almost sounds like begging the question; Python's also more
acceptable (to some) because it is more popular. Python may stay more
popular because the differences between Ruby and Python are too subtle
for most people to care (or too sophisticated for most people to
understand), and Python (currently) has the edge on available libraries.



James
 
G

gabriele renzi

il Fri, 2 Jul 2004 16:02:34 +0900, David Garamond
+ it's purely object-oriented (unlike Python & Perl), thus functional or
procedural guys might get offended or turned off.

actually the python guys would strongly disagree. Python is pure-oo
since v2.2 IIRC
 
G

gabriele renzi

il Fri, 2 Jul 2004 14:27:09 +0900, Nicholas Van Weerdenburg
<[email protected]> ha scritto::

I believe Groovy had a greater acceptance than Jython beetween
javaers. The step is simpler from java to grrovy, they have both lots
of {} :)

The advantage jython has, imo, over JRuby are:
- time. It existed before
- it has jythonc that allows use to compile to jvm bytecode.

OTOH JRuby is, well, ruby :) while the stable jython is a python 2.1,
which is quite updated and inferior, imo, to current python.

PNuts is also interesting in the jvm scripting world
 
B

Ben Giddings

gabriele said:
actually the python guys would strongly disagree. Python is pure-oo
since v2.2 IIRC

Whoa, depends on how you define 'pure-oo'. Maybe they are OO under the
covers, but the interface (which has remained backwards-compatible) sure
isn't very OO.

Take for example, 'len', it's not a property of Strings or Arrays, it's
a function you apply to them to get their length. Same goes for 'map',
it's not a property of lists or arrays, it's just a function.

Maybe behind the scenes Integers are now objects, but that sure doesn't
make the language seem very 'pure-oo'.

Ben
 
G

gabriele renzi

il Sat, 3 Jul 2004 02:56:21 +0900, Ben Giddings
Whoa, depends on how you define 'pure-oo'. Maybe they are OO under the
covers, but the interface (which has remained backwards-compatible) sure
isn't very OO.

I define it as: everything is an object
Take for example, 'len', it's not a property of Strings or Arrays, it's
a function you apply to them to get their length. Same goes for 'map',
it's not a property of lists or arrays, it's just a function.

actually, len is just a commodity, the length of an array is actually:
ary=[1,2,3,4]
ary.__len__()
4

Maybe behind the scenes Integers are now objects, but that sure doesn't
make the language seem very 'pure-oo'.

not behind the scenes:
I'm not really a python guru, but for the definition of 'pure oo' as
'everything that gets assigned to a variable name is an object', it
is.

If your definition is based on type(x) being less pure then x.class..
well, then it's not OO.
(obviously x.__class__() works fine in python ;)
 
A

Ara.T.Howard

Take for example, 'len', it's not a property of Strings or Arrays, it's a
function you apply to them to get their length. Same goes for 'map', it's
not a property of lists or arrays, it's just a function.

i happen to agree with you, but you are on a slippery slope i think: one
could make the argument that

open path

in ruby is not very OO. it's simply a function you apply to strings to get
an fd for them. of course, it happens to be pinned on Kernel (or Object - i
forget which) but this is really splitting hairs isn't it? after all, whilst
one could easily make the argument that the method len used for determining
the length of strings, THE fundemental data structure according to all of
computer science, should belong in Object and that open should not.

popen3 is another fine example - very useful, not very OO. i guess i view
ruby as very OO where it should be, and not very OO other places: take for
example the control of child processes, thier execution, input/output/errput,
status, communication, etc. - nothing OO about it. i for one though, am glad
it isn't because i can use 'man' to navigate through much the non-OO stuff.
java tried pretty hard to force some non-OO things into OO boxes (more like
wet squashed bags) and it was terrible - remember the first time you tried to
read a file in java? yuck.

in any case i always doubt the merit of saying ruby is more OO than 'x' and
therfore better. i'll personally say that i can solve problems quicker and
more enjoyably in ruby that in any other lang i know - but that's just me.

kind regards.

-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| A flower falls, even though we love it;
| and a weed grows, even though we do not love it.
| --Dogen
===============================================================================
 
D

David Garamond

gabriele said:
il Sat, 3 Jul 2004 02:56:21 +0900, Ben Giddings


I define it as: everything is an object

Define 'everything' then :) Not even everything (like control
structures or the program itself) is an object in Ruby.

Btw, there are other definitions, e.g. we communicate with an object by
passing messages (e.g. invoking its methods). An object in Python, IIRC,
is more like a bag of attributes which you can (or tend to) access
directly. I view Ruby much more pure-OO than Python in this regard.
 
L

Lennon Day-Reynolds

[...]
Define 'everything' then :) Not even everything (like control
structures or the program itself) is an object in Ruby.

Oh, but only if they were...who needs macros, if you have a reflection
API that extends to program flow and compiled code structures?

Lennon
 
G

gabriele renzi

il Sat, 3 Jul 2004 04:19:12 +0900, David Garamond
Define 'everything' then :) Not even everything (like control
structures or the program itself) is an object in Ruby.

look at the end of the message :)
'everything that gets assigned to a variable name is an object'
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top