[Ecls-list] Simple Hello word! function

Pascal J. Bourguignon pjb at informatimago.com
Sun Jul 4 00:24:55 UTC 2010


Louis Höfler <louis.hoefler at gmx.de> writes:

> Hello everyone.
> I wrote a simple (yet unstable and not tested)
> module for apache. It allows execution of
> lisp code like php code.
> You can download it here
> https://sourceforge.net/projects/mod-ecl/
> However. I try to execute this simple function:
> (defun hello-world () (print "Hello world!")) (hello-world)
> But the only thing printed out is
> hello-world
> If I copy paste the same code into ecl
> it also prints out hello-world.
> If I paste
> (defun hello-world () (print "Hello world!"))
> then press return
> then paste (hello-world)
> the string Hello world! is printed out.
> What am I doing wrong?

Expecting that the REPL will evaluate all the sexps you give it in one
chunk.

Or in your case, your very own ecl_eval function.

I find it a little confusing to name functions with the same prefix as
one library you use.  What if a new version of that library now
provides its own ecl_eval function?

Perhaps you should first rename that function something like
mod_ecl_eval().

The second problem you have with this function,  is that it has no
specification, no comment documenting its behavior.

If you had written:

    cl_object ecl_eval(char* code)
    /*
        Reads ONE expression from the C string code, and evaluates it.
        Returns the primary value returned from the evaluation of this
        expression.
    */
    {
        ...
    }

then perhaps it would be clear why ecl_eval("(defun ...) (...)") just
does the defun and ignores the second expression.


Of course, I know it, and you knew it (since you called it several
times in sequence to evaluate several expressions, as for example, in
ecl_disable_console (which also lacks a documentation string^W
comment).  But obviously, you FORGOT it!   Why do you think we're
telling you to put documentation comments in your sources!


Now, you could instead define a function to evaluate all the
expressions it can read from a string.  For example, you could specify
a function that would:

    Read expressions from the strings and evaluates them in sequence,
    until an error occurs, or no expression remains.  Returns a list of
    lists, each sublists containing either:
        (T   start-pos end-pos expression-read-and-evaluated T   result-values)
        (T   start-pos end-pos expression-read-and-evaluated NIL error-condition)
        (NIL start-pos end-pos unreadable-substring          NIL error-condition)
    The first sublist with NIL in its fifth position will be also the last of the
    result.

Such as:

> (eval-from-string "(+ 1 2) (truncate 10 3) (* 3")

((T 0 8 (+ 1 2) T (3))
 (T 8 24 (TRUNCATE 10 3) T (3 1))
 (NIL 24 28 "(* 3" NIL #<a END-OF-FILE>))

Then you could take out the returned list and report results or
errors.





(defun eval-from-string (string)
  "
Reads expressions from the strings and evaluates them in sequence,
until an error occurs, or no expression remains.  Returns a list of
lists, each sublists containing either:
    (T   start-pos end-pos expression-read-and-evaluated T   result-values)
    (T   start-pos end-pos expression-read-and-evaluated NIL error-condition)
    (NIL start-pos end-pos unreadable-substring          NIL error-condition)
The first sublist with NIL in its fifth position will be also the last of the
result.
"
  (loop
     :with result = '()
     :with slength = (length string)
     :with start = 0
     :for current = start
     :while (< start slength)
     :do (multiple-value-bind (form end)
             (handler-case
                 (read-from-string string t nil :start current)
               (t (err)
                 (push (list nil current slength (subseq string current) nil err) result)
                 (return-from eval-from-string (nreverse result))))
           (setf start end)
           (handler-case
               (push (list t current end form t (multiple-value-list (eval form))) result)
             (t (err)
               (push (list t current end form nil err) result)
               (return-from eval-from-string (nreverse result)))))
     :finally (return-from eval-from-string (nreverse result))))

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/





More information about the ecl-devel mailing list