libera/#lisp - IRC Chatlog
Search
7:45:14
rendar
if i type '2' in lisp repl, i get 2, but in such a case i'm not typing a s-expr, so.. the parser checks if there are ( ) and parses an s-expr, otherwise just evaluate?
7:59:07
moon-child
the result of reading the string "2" is the number 2. The result of evaluating the number 2 is also the number 2. This 2 is then printed
7:59:30
moon-child
the result of reading, for instance, (+ 5 7) is the list whose first element is the symbol +, etc.
8:01:14
moon-child
if you type, for instance, (+ 5 7) (+ 3 4), you will see that, just as in the example with 1 2 3 4, it reads (and prints the result from evaluating) multiple forms. Parentheses have nothing to do with it, except that most forms which do anything interesting when evaluated involve conses, and most strings which when read include conses involve parentheses
8:02:40
rendar
well, my lisp parser parses lexemes returned from the lexer, if it gets `Lexeme_OPEN Lexeme_TEXT(+) Lexeme_TEXT(2) Lexeme_TEXT(3) Lexeme_CLOSE` it can successfully build a tuple of `(+, 2, 3)` which is also an s-expr, then evaluator will evaluate that s-expr, but if it doesn't get the lexems for opening and closing ( ), what the parser will produce? it won't produce an s-expr..
8:05:24
moon-child
then your 'lisp parser' is bizarre and unorthodox, and you are unlikely to get a useful result here
8:07:58
moon-child
in lisp, the reader is a function (which is a kind of lisp object) which takes a string such as "(+ 2 3)" (which is also a kind of lisp object) and returns another lisp object (such as the list comprising the symbol named +, the number 2, and the number 3)
8:10:49
moon-child
the implementation of the reader does not need to work with any data structures more sophisticated than that
8:26:09
rendar
moon-child, fine, but if reader reads "(+ 2 3)" it returns a list, if it reads "2" it doesn't return a list
8:27:50
rendar
when the parser parses "(something)" with ( ), it will be an s-expr, and the default behavior for an s-expr is that the first argument is a function ok?
8:30:34
moon-child
I don't know what an s-expr is. But yes, when you read the string "2", you will not get a list. What's wrong with that?
8:34:24
moon-child
in accordance with local hyperspec regulations: http://www.lispworks.com/documentation/lw60/CLHS/Body/26_glo_f.htm#form
9:05:24
TMA
a s-expression is either an atom or a pair (aka cons) whose head and tail (first and rest / car and cdr) are s-expressions
9:07:52
moon-child
TMA: as far as I can tell, the term 's-expression' refers broadly to a class of semi-uniform parenthesis-oriented syntaxes
9:08:22
moon-child
it can be compared, for instance, with m-expressions; the equivalent m-expression to (+ 1 2) is +[1;2]
9:09:52
TMA
moon-child: well, yes and no. m-expressions do not describe data, s-expressions do. that's why there is the QUOTE special form, which is unnecessary in m-expressions
9:13:55
TMA
well, I think we have a different and slightly incompatible mental model; we are not refering to the same things even though we are using the same words
9:15:27
TMA
a lisp interaction job can be approximated by this simplified REPL (read-eval-print-loop):
9:17:48
TMA
read reads a stream of characters and produces a lisp datum (datum is the singular of data)
9:19:03
TMA
it returns a lisp datum that is the result of the evaluation; that datum is called a value
9:22:51
TMA
well, there is no difference in itself. it just describes the difference in usage; if you have three numbers, say 1, 2 and 3 and an equation 1 + 2 = 3, you say that 1 and 2 are addends while 3 is their sum
9:26:26
moon-child
then 3 is the value that results from the addition. But 2 is the value that results from the subtraction
9:27:13
moon-child
sham1: sure, but you can whack everything with the identity as many times as you like and it remains the same
9:32:34
TMA
if it is a symbol, the value of the form is the datum associated with the symbol in the evaluation environment
9:33:54
TMA
if it is the pair, the head shall be an operator designator in the evaluation environment
9:34:46
TMA
if the operator designated by the operator designator is a special operator, the form is evaluated by the rule for the special operator
9:35:33
TMA
if the operator designated by the operator designator is a macro, the macro function is applied to the form and the current evaluation environment
9:37:14
TMA
otherwise the rest of the form shall be a proper list of forms and the operator is applied to a list of the forms' values
9:38:30
pjb
rendar: formally S-expression is the textual form. But since we use textual forms that are readable, to be able to read them and convert them into lisp objects, and since printing those lisp objects readably will produce the same S-expression (modulo insignificant variations), we tend to use the term S-expression for those lisp objects too.
9:38:55
pjb
rendar: but note that some lisp objects are not printable readably: they produce a S-expression of the form #<…> which produces an error when read.
9:39:55
pjb
rendar: this doesn't say much since anything that is not a cons cell (ie. a possibly dotted list), is an atom.
9:40:12
pjb
(defclass koo () ()) #| --> #<standard-class koo> |# (make-instance 'koo) #| --> #<koo #x302004DDEB2D> |#
9:40:40
TMA
if you would opt to disregard the form--value--datum distinction, the description would be way more difficult to understand
9:40:50
pjb
here you can see that class objects, or instances of classes are not printable readably (by default). You may provide print-object methods on them to provide a printable readabaly form.
9:41:38
pjb
So, EVAL takes a lisp object, interprets it as a lisp form (ie an executable expression), and returns the computed values.
9:42:05
pjb
Note that you will enter eval forms at the REPL in general, and there's already an eval here, in the rEpl!
9:42:24
pjb
So you must be careful to avoid evaluation by the REPL of the arguments you want to give to your EVAL.
9:43:20
pjb
(eval (+ 1 2)) will have (+ 1 2) be evaluated before calling EVAL, by the eval in the REPL. So you are actually calling (eval 3)
9:43:54
pjb
You can see the difference with: (eval '(truncate 10 3)) #| --> 3 ; 1 |# vs. (eval (truncate 10 3)) #| --> 3 |#
9:44:48
pjb
Now, in REPL, there's also a LOOP ! So when you give 1 2 3 4 to the REPL, it will loop reading first the 1, evaluating it, printing the result 1, then reading the 2, evaluating it, and printing 2, and so on looping while there's input.
10:00:30
pjb
rendar: note that CL eval works with the NIL environment, ie. the global environment. No local lexical variables. Only inner-eval has an environment parameter where it can find the local bindings.
10:01:34
pjb
rendar: eval will have to have a case for each special operators: (let (specops) (do-external-symbols (s "CL") (when (special-operator-p s) (push s specops))) specops) #| --> (catch tagbody locally function progn symbol-macrolet multiple-value-prog1 flet the progv unwind-protect return-from throw go let* if block load-time-value labels quote setq eval-when multiple-value-call macrolet let) |#
15:42:40
theseb
Is a function invocation able to modify the environment? The reason I'm not sure is I'm aware functions are evaluated in "special" environments saved when the functions were defined.
15:45:01
theseb
Let me try to ask the same question a different way....Suppose you define a function in envX. Suppose you invoke the function in envY. Will the invocation modify envY as well as envX?
15:46:31
theseb
My limited understanding of "lexical scoping" is that invocations use envX when evaluating the function body?
15:51:36
theseb
It just seems weird to me for some reason today that inside a function you can't modify the normal environment
15:51:58
theseb
But I think that is what people mean when they talk about stuff happening in different "scopes"
16:41:05
White_Flame
rendar: if you do want to use more standard terminology, lisp does not use a lexer+parser, it uses a reader which does not cleanly delineate between those 2
16:41:33
TMA
theseb: it depends. when you do (setf a b) where x is a lexical binding the value associated with a in envX is changed; if the binding is dynamic (called special in Common Lisp parlance) the value in envY is changed; it is conventional to name the variables whose bindings are special with earmufs: *name*
16:41:46
rendar
White_Flame, i see, problem is that i have already written a lot of code, and i have a Lexer and Parser classes.. hard to revert back
16:43:16
rendar
White_Flame, for now, i have the Lexer yielding (with python generators) Tokens, the parsers reads these tokens and yields Form classes, the Interpreter will eval these forms, and the REPL will print Interpreter form's eval results
16:44:37
rendar
now i'm fixing the problem that the lexer/parser can get incomplete code, e.g. getting first "(+ 2" and then "3)"
16:47:55
White_Flame
the reader only performs parsing which is purely syntactic; the evaluator performs parsing which involves semantic location of code
16:48:38
White_Flame
also, if the reader (which uses a string), gets "(+ 2" and end-of-stream, it is an error