www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Code Comparison - Seeking D Equivalent to Lisp "dofile"

reply "Tony" <ignorethis nowhere.com> writes:
I'm torn between D and Lisp.

In order to compare the two, I was wondering if anyone could provide me with 
the D equivalent of the following Lisp macro "dofile".

dofile allows code such as the following to be written:

(dofile (line "path-to-file")
    (do-something-with-each-line))

For example:

(dofile (line "c:/myfile.txt")
    (print line))

The above code would open the (text only) file, print each line and then 
close the file.  It should be noted that the body of the dofile is not 
limited to one expression (it can contain any number of expressions).

In case anyone is interested, here is the Lisp code for dofile:

(defmacro dofile ((line file-path) &body body)
    (let ((in-stream (gensym "IN-STREAM-")))
        `(with-open-file (,in-stream ,file-path :direction :input 
:if-does-not-exist nil)
       (if (eql ,in-stream nil)
           nil
           (do ((,line (read-line ,in-stream nil) (read-line ,in-stream 
nil)))
               ((null ,line) t)
              , body)))))


Tony
Melbourne, Australia
tonysZ-mailboxZ hotmailZ.com  (remove the Zs) 
Feb 18 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Tony" <ignorethis nowhere.com> wrote in message 
news:dt8rlm$nvn$1 digitaldaemon.com...
 I'm torn between D and Lisp.
That someone could ever say that just.. blows my mind :)
 In order to compare the two, I was wondering if anyone could provide me 
 with the D equivalent of the following Lisp macro "dofile".

 dofile allows code such as the following to be written:

 (dofile (line "path-to-file")
    (do-something-with-each-line))

 For example:

 (dofile (line "c:/myfile.txt")
    (print line))

 The above code would open the (text only) file, print each line and then 
 close the file.  It should be noted that the body of the dofile is not 
 limited to one expression (it can contain any number of expressions).

 In case anyone is interested, here is the Lisp code for dofile:

 (defmacro dofile ((line file-path) &body body)
    (let ((in-stream (gensym "IN-STREAM-")))
        `(with-open-file (,in-stream ,file-path :direction :input 
 :if-does-not-exist nil)
       (if (eql ,in-stream nil)
           nil
           (do ((,line (read-line ,in-stream nil) (read-line ,in-stream 
 nil)))
               ((null ,line) t)
              , body)))))
import std.stream; ... File f = new File(`c:\myfile.txt`, FileMode.In); foreach(char[] line; f) writefln(line); How about that? Not bad. And certainly more readable than your little sea of parentheses you've got there ;) Or, if you're feeling a little more adventurous, you can take advantage of D's function/delegate literals: void dofile(char[] fileName, void delegate(char[] line) dg) { // Note the "auto" - the file will be automatically closed when the // function returns. auto File f = new File(fileName, FileMode.In); foreach(char[] line; f) dg(line); } ... dofile(`c:\myfile.txt`, delegate void(char[] line) { writefln(line); } );
Feb 18 2006
next sibling parent reply "Tony" <ignorethis nowhere.com> writes:
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message 
news:dt8tee$uq6$1 digitaldaemon.com...
 "Tony" <ignorethis nowhere.com> wrote in message 
 news:dt8rlm$nvn$1 digitaldaemon.com...
 I'm torn between D and Lisp.
That someone could ever say that just.. blows my mind :)
 In order to compare the two, I was wondering if anyone could provide me 
 with the D equivalent of the following Lisp macro "dofile".

 dofile allows code such as the following to be written:

 (dofile (line "path-to-file")
    (do-something-with-each-line))

 For example:

 (dofile (line "c:/myfile.txt")
    (print line))

 The above code would open the (text only) file, print each line and then 
 close the file.  It should be noted that the body of the dofile is not 
 limited to one expression (it can contain any number of expressions).

 In case anyone is interested, here is the Lisp code for dofile:

 (defmacro dofile ((line file-path) &body body)
    (let ((in-stream (gensym "IN-STREAM-")))
        `(with-open-file (,in-stream ,file-path :direction :input 
 :if-does-not-exist nil)
       (if (eql ,in-stream nil)
           nil
           (do ((,line (read-line ,in-stream nil) (read-line ,in-stream 
 nil)))
               ((null ,line) t)
              , body)))))
import std.stream; ... File f = new File(`c:\myfile.txt`, FileMode.In); foreach(char[] line; f) writefln(line); How about that? Not bad. And certainly more readable than your little sea of parentheses you've got there ;) Or, if you're feeling a little more adventurous, you can take advantage of D's function/delegate literals: void dofile(char[] fileName, void delegate(char[] line) dg) { // Note the "auto" - the file will be automatically closed when the // function returns. auto File f = new File(fileName, FileMode.In); foreach(char[] line; f) dg(line); } ... dofile(`c:\myfile.txt`, delegate void(char[] line) { writefln(line); } );
Thanks Jarrett. Your dofile function seems to have most of the functionality of the Lisp macro. And I'm forced to admit that it is a little more readable than my "little sea of parentheses" :) I would have to say that D comes out ahead in this particular instance. Tony Melbourne, Australia tonysZ-mailboxZ hotmailZ.com (remove the Zs)
Feb 18 2006
parent reply John Demme <me teqdruid.com> writes:
Tony wrote:
 Thanks Jarrett.
 
 Your dofile function seems to have most of the functionality of the Lisp
 macro.  And I'm forced to admit that it is a little more readable than my
 "little sea of parentheses" :)
 
 I would have to say that D comes out ahead in this particular instance.
 
 Tony
 Melbourne, Australia
 tonysZ-mailboxZ hotmailZ.com  (remove the Zs)
I'd like to point out that none of this has to do with D itself but rather the standard library. This isn't to belittle the library (I prefer to make fun of phobos separately) but this example is more telling of the language itself; that D allows such expressive syntax-- the overloadable foreach in this case. ~John Demme
Feb 18 2006
parent "Charles" <noone nowhere.com> writes:
  This isn't to belittle the library (I prefer to make
 fun of phobos separately)
:D "John Demme" <me teqdruid.com> wrote in message news:dt95k5$1mad$1 digitaldaemon.com...
 Tony wrote:
 Thanks Jarrett.

 Your dofile function seems to have most of the functionality of the Lisp
 macro.  And I'm forced to admit that it is a little more readable than
my
 "little sea of parentheses" :)

 I would have to say that D comes out ahead in this particular instance.

 Tony
 Melbourne, Australia
 tonysZ-mailboxZ hotmailZ.com  (remove the Zs)
I'd like to point out that none of this has to do with D itself but rather the standard library. This isn't to belittle the library (I prefer to
make
 fun of phobos separately) but this example is more telling of the language
 itself; that D allows such expressive syntax-- the overloadable foreach in
 this case.

 ~John Demme
Feb 20 2006
prev sibling parent reply David Medlock <noone nowhere.com> writes:
Jarrett Billingsley wrote:

 "Tony" <ignorethis nowhere.com> wrote in message 
 news:dt8rlm$nvn$1 digitaldaemon.com...
 
I'm torn between D and Lisp.
That someone could ever say that just.. blows my mind :)
In order to compare the two, I was wondering if anyone could provide me 
with the D equivalent of the following Lisp macro "dofile".

dofile allows code such as the following to be written:

(dofile (line "path-to-file")
   (do-something-with-each-line))

For example:

(dofile (line "c:/myfile.txt")
   (print line))

The above code would open the (text only) file, print each line and then 
close the file.  It should be noted that the body of the dofile is not 
limited to one expression (it can contain any number of expressions).

In case anyone is interested, here is the Lisp code for dofile:

(defmacro dofile ((line file-path) &body body)
   (let ((in-stream (gensym "IN-STREAM-")))
       `(with-open-file (,in-stream ,file-path :direction :input 
:if-does-not-exist nil)
      (if (eql ,in-stream nil)
          nil
          (do ((,line (read-line ,in-stream nil) (read-line ,in-stream 
nil)))
              ((null ,line) t)
             , body)))))
import std.stream; ... File f = new File(`c:\myfile.txt`, FileMode.In); foreach(char[] line; f) writefln(line); How about that? Not bad. And certainly more readable than your little sea of parentheses you've got there ;)
If you ever sit down and learn Scheme or Lisp, you will understand those parentheses serve very important capabilities. Features such as try/catch, conditionals, templates, type systems and many other features are easily added to Lisp due to its AST syntax. Delegates equivalent to what *all* functions are in Lisp. Templates are not needed because a Lisp macro is a function which accepts a Lisp program and returns a Lisp program! Semantically its easily more powerful than D or C++, with D probably 2-3x faster in most cases. -DavidM
Feb 20 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"David Medlock" <noone nowhere.com> wrote in message 
news:dtcig0$1rnd$1 digitaldaemon.com...
 If you ever sit down and learn Scheme or Lisp, you will understand those 
 parentheses serve very important capabilities.  Features such as 
 try/catch, conditionals, templates, type systems and many other features 
 are easily added to Lisp due to its AST syntax.

 Delegates equivalent to what *all* functions are in Lisp.
 Templates are not needed because a Lisp macro is a function which accepts 
 a Lisp program and returns a Lisp program!

 Semantically its easily more powerful than D or C++, with D probably 2-3x 
 faster in most cases.
I'm not ragging on Lisp; I'm just saying that the C syntax is somewhat more readable and clean-looking than a million parentheses.
Feb 20 2006
parent David Medlock <noone nowhere.com> writes:
Jarrett Billingsley wrote:

 "David Medlock" <noone nowhere.com> wrote in message 
 news:dtcig0$1rnd$1 digitaldaemon.com...
 
If you ever sit down and learn Scheme or Lisp, you will understand those 
parentheses serve very important capabilities.  Features such as 
try/catch, conditionals, templates, type systems and many other features 
are easily added to Lisp due to its AST syntax.

Delegates equivalent to what *all* functions are in Lisp.
Templates are not needed because a Lisp macro is a function which accepts 
a Lisp program and returns a Lisp program!

Semantically its easily more powerful than D or C++, with D probably 2-3x 
faster in most cases.
I'm not ragging on Lisp; I'm just saying that the C syntax is somewhat more readable and clean-looking than a million parentheses.
Yeah, that is the thorn people touch when they encounter Lisp/Scheme and language readability is a very valid issue. I just didn't want anyone to be turned off to trying it from that issue alone. Like Perl, if you can stand the syntax you will probably find the semantics very good. -DavidM
Feb 20 2006