libera/commonlisp - IRC Chatlog
Search
18:00:22
contrapunctus
Good, so I don't have to copy-paste my NIH version of that in all my projects ^^'
18:18:14
contrapunctus
White_Flame: heh. When I was about to copy-paste it into a third project, I realized that there _had_ to be something for this in some util library somewhere.
19:38:20
dlowe
fourier: checking for it in initialize-instance seems to be a reasonable choice, though you might want to check for it in reinitialize-instance too
19:56:05
Krystof
I'm missing context, but if this is about an initarg check for a standard object, you might want to do it in shared-initialize
19:56:27
Krystof
(which will catch initialization, reinitialization, change-class and class redefinition)
20:44:12
dlowe
so the context is making sure a class-slot is initialized to something passed into make-instance
21:13:57
pjb
rendar: in smalltalk a message is: object message: arg1 msg: arg2 . to send a message named message:msg: with arg1 and arg2 to object.
21:14:30
pjb
rendar: The syntax for blocks (lambda): [ parameters | local variables | messages … ^ result ]
21:14:57
pjb
often in the code, we use thunks, ie. lambda without parameters: [ | local variables | … ]
21:16:14
pjb
rendar: now, I implemented a reader macro similar to Objective-C for Common Lisp : Objective-CL
21:16:46
pjb
rendar: https://gitlab.com/com-informatimago/com-informatimago/-/blob/master/objcl/documentation.pdf
21:17:53
pjb
rendar: it would need an overhaul to be able to work with all the Objective-C runtime via all the FFI (ie. CFFI) on all the CL implementations. For now, it works mostly with the Apple runtime on CCL (and CFFI but also some CCL specific FFI).
21:18:29
rendar
i'm interesting in deep understanding the differences between smalltalk/objc blocks vs. s-expressions
21:18:36
pjb
This files gives some examples: https://gitlab.com/com-informatimago/com-informatimago/-/blob/master/objcl/howto.lisp
21:19:49
pjb
We can use such literal lisp data to represent programs: (if (= a b) (princ "equal") (princ "different"))
21:20:39
pjb
We can write programs called interpreters or compilers, to evaluate such programs. There's CL:EVAL, CL:COMPILE, and CL:COERCE that can convert S-expressions representing programs into lisp execution or compiled lisp functions.
21:21:09
pjb
To represent a function we use the data syntax: (lambda (a b) (if (= a b) (princ "equal") (princ "different")))
21:21:24
pjb
And we can compile it: (compile nil (quote (lambda (a b) (if (= a b) (princ "equal") (princ "different"))))) #| --> #<Anonymous Function #x302008B990DF> ; nil ; nil |#
21:21:41
pjb
We can then call this function: (let ((fun (compile nil (quote (lambda (a b) (if (= a b) (princ "equal") (princ "different"))))))) (funcall fun 1 2)) #| different --> "different" |#
21:22:13
pjb
Here the s-expression is a literal (as denoted by the quote operator); but you can also build it with your own programs.
21:22:27
pjb
Oh! Note that the program (let ((fun (compile nil (quote (lambda (a b) (if (= a b) (princ "equal") (princ "different"))))))) (funcall fun 1 2)) is also a S-expression!!!
21:23:28
pjb
This works because the lisp system contains a REPL and a file compiler and file loader that will read those S-expressions, and pass them to CL:EVAL automatically: (LOAD "file.lisp") or (COMPILE-FILE "file.lisp"), or the REPL.
21:23:46
pjb
the REPL is a Read Eval Print Loop that is the basis of interaction with the lisp system.
21:24:15
pjb
When you type a S-expression in the REPL, it is first READ, ie the text you type is converted to a lisp data structure (a list if it starts with "(").
21:24:42
pjb
THen this lisp data structure is passed to CL:EVAL which will interpret it, and return the result. The result is passed to PRINT which prints it.
21:26:05
pjb
rendar: Smalltalk blocks are like lisp anonymous functions. They can be written in S-expression as: (lambda (parameters…) (let ((local) (variables) …) body expressions result))
21:26:49
pjb
So you can write (defmethod ifThen ((test T #| generalized boolean |#) thunk) (if test (funcall thunk)))
21:28:09
pjb
and since we represent lisp program sources as lisp data, you can use S-expressions to write all lisp programs.
21:28:57
pjb
In almost all other languages, the source is defined as a text file, ie a string of characters.
21:29:26
pjb
But in lisp, the source is lisp data (cons cells, atoms, numbers, strings, etc). This is what is processed by EVAL or COMPILE.
21:29:45
pjb
Only this lisp data can be read with CL:READ, from the S-expression form (which is also a textual representation).
21:30:13
pjb
And since there's also a printer CL:PRINT to print S-expressions, we can print and read and print back code (or data).
21:31:14
pjb
Now, there are some types of lisp objects that don't have a readable print syntax. Eg. packages: *package* #| --> #<Package "COMMON-LISP-USER"> |# It starts with #< which cannot be read.
21:32:36
pjb
But for you own classes of objects, you can define a method on the PRINT-OBJECT generic function to print them readably.
21:33:07
pjb
For example, CCL does this for random states: *random-state* #| --> #.(ccl::initialize-mrg31k3p-state 1662898282 955392070 420261365 823417203 431141722 953184299) |# It uses the #. syntax which reads a form and evaluates to read the object.
21:34:02
pjb
rendar: yes, and no. The thing is that the grammar is trivial. There's a lexical analysis which is specified in the chapter 2 of CLHS, as the "lisp reader algorith", and all the rest of the syntax is defined as reader macros and dispatching reader macros.
21:34:30
pjb
The lisp reader algorithm knows only how to read symbols, integers, ratio and floating point numbers.
21:35:53
pjb
We can give a coarse grammar for S-expr, but this is only what lisp does by default, with the default reader macros. You can install your own reader macros, and change that syntax.
21:36:23
pjb
rendar: AFAIK nope. There's a copyright on the web site. IIRC gcl had the authorization to make a copy in info format.
21:37:10
pjb
rendar: the ANSI/ISO organization will sell you for dear money a PDF of the standard, which is a bad scanning of a paper printout. It's not worth paying for it, unless you need it for legal reasons.
21:38:19
pjb
atom ::= integer | ratio | float | string | structure | … . all literal lisp object syntaxes specified by the reader macros.
21:38:56
pjb
rendar: I like ccl. sbcl is liked by a lot of people because it generate fast code, but it has the inconvenient of having a new release each month!!!
21:39:18
pjb
rendar: abcl is nice if you want to run on the JVM. ecl is nice if you want to embed it with C applications.
21:40:03
pjb
rendar: I find clisp nice for newbies, since it contains an interpreter, and some niceties, (but a lot of people don't like it because it has new releases each 10 or 20 years, and compiles to a VM).
21:48:59
pjb
rendar: note that you may prefer to read some book or lisp tutorial before reading the CLHS, since the later is not pedagogical at all (it's a language reference).
0:53:40
Roy
I was over on #programming and discussing what we on #programming talk about and said how I hate OO, but like CLOS and multi-dispatch.
2:19:04
nij-
People have also been arguing that trigonometry doesn't help when you buy groceries, therefore it's useless.
3:18:37
nij-
beach > Is it true that any language that has throw/catch + dynamic variables can implement a conditions system as powerful as Lisp's?
3:21:26
Bike
the way the condition system works, handlers are executed during signaling, but signal can just return normally.
3:21:35
beach
nij-: The power of the condition system is not due to any complicated implementation technique. It comes from implementing the right abstractions. Otherwise, the condition system is quite simple.
3:21:36
Bike
so you need to be able to run code in its original context, like its lexical environment.
3:22:27
Bike
it is possible, sorta. i think the windows C++ exception handling do... something like it. "funclets". i haven't looked into it much.
3:26:42
Bike
the resumptive quality is critical to how lisp conditions work and it's not common in other languages. if you don't allow handlers to resume, your implementation can just unconditionally jump up the stack frames and there ya go.
3:48:08
nij-
But Bike was answering "nij- > Why do we need first class functions?" which might be hard to answer though..
3:51:34
nij-
But I'm aware it's not always an easy task.. I often found it hard to explain something I know well too :(
3:57:19
beach
The point, though, is that when you design a language, you should include the low-level primitives that allow you to build powerful, yet simple, high-level mechanisms.
4:04:52
Bike
the basic nature of exceptions or conditions or whatever is that you have a function F call a function G, and G transfers control to F in some way other than returning normally.
4:05:26
Bike
in most languages that's one way: G does an abnormal exit and you're back in a "handler" in F. but in lisp the handler can decide G is actually doing fine, and control can resume in G somewhere.
4:06:12
Bike
because of this, it has to be possible for the handler code to run without permanently exiting G.
4:06:37
Bike
the simple way to do this, which implementations generally do, is to have the handler be a first class function that the signaling code in G just calls normally.
4:10:52
nij-
It makes more sense! Thank you, Bike. However, why can't the handler be a non-first class function? After all, the signaling code G can call a non-first-class function.
4:14:21
beach
nij-: If it is not a first-class function, it would have to be invoked by name, like (handler ...), but the name is not known statically.
4:15:18
beach
nij-: The handler must be looked up in the dynamic environment, i.e., the call stack. And then, it must be possible to manipulated like any other value, like (funcall (find-handler ...) ...) which requires a first-class function.
4:16:43
beach
nij-: An entity that is first class is one that can be the value of a variable, can be passed as the argument to a function, and can be returned as the value of a function call.
4:18:57
nij-
That's what I understand. Ah I see.. otherwise you need to refer by name which is not so convenient.
4:20:18
nij-
--- Is there a bug in the examples of this CLHS page? http://www.lispworks.com/documentation/lw70/CLHS/Body/f_invo_1.htm