freenode/#lisp - IRC Chatlog
Search
21:50:09
HiRE
hmm, upon defining a class (defclass blankaccount () (customer-name balance)) and loading it into SLIME
21:50:15
pjb
vms14: right. I would have used OO. All those functions are just methods of the same generic function generate taking arguments php-node
21:53:37
pjb
When I type (make-instsance 'ba it completes alone, I just type TAB to finish it without typo.
21:55:18
pjb
Sorry, wrong file; go to: https://github.com/informatimago/lisp/blob/master/languages/linc/c-syntax.lisp#L202
21:56:27
pjb
So of course, you need to define classes for the syntactic elements: https://github.com/informatimago/lisp/blob/master/languages/linc/c-syntax.lisp#L173
21:57:06
pjb
And write a parser or macros to convert a sexp into a tree of instances of those classes.
21:58:23
pjb
(generate (parse '(defun foo (x y) (+ y x)))) -> <php?>number foo(x:number,y:number){return y+x;}</php> or whatever the php syntax is.
22:04:25
vms14
It seems much better way than how I'm doing, but I have to think now, I have no idea about where to start
22:05:37
pjb
You could start from the php grammar, if you want to implement a complete syntax. (This can be useful if you want to be able to parse php back to sexps).
22:06:25
pjb
Or you can just choose a sane subset. For example, for C or C++, it would be crazy to use the actual language grammar. Instead, you can define the grammar for a subset language as is used by human programers.
22:07:35
pjb
Similarly, the sexps syntax you will define can be able to express only a subset of the whole syntax (the subset you would use as a human programmer, or you need to generate), it doesn't necessarily have to cover the whole syntax.
22:09:09
pjb
You can also implement a php-parser and generate the sexp from it: php-source -> ast-objects -> sexp.
22:09:28
pjb
So you can parse php, get a sane sexp, edit or transform it automatically, and generate back the php.
22:09:57
vms14
would be nice, but also more complicated to write both, and I don't know if I'll need that
22:38:21
pjb
vms14: it's easy. In the case of lisp sexps, eg. if: (if <test> <then> [<else>]) -> (defclass lisp-if (lisp-expression) ((<test> :initarg :test :reader if-test) (<then> :initarg :then :reader if-then) (<else> :initarg :else :initform nil :reader if-else)))
22:39:06
pjb
vms14: then: (defmacro my-sexpified-language:if (<test> <then> &optional <else>) (make-instance 'lisp-if :test <test> :then <then> :else <else>))
22:40:24
pjb
Having classes has the big advantage that you can write generic functions dispatching on them, to do all kind of stuff on the programs thus represented. You can generate them in different languages, compile them to lisp or native code, pretty print them, transform them, etc.
22:41:03
White_Flame
I find it often yields smaller, more manageable code to do the same thing with plain data structures and manual functions
22:43:01
White_Flame
but yeah, it's still a tool in the toolbox. Just don't go all Java "OO = Object Obsessed" ;)
22:44:46
vms14
I don't see many advantadges using CLOS instead of just functions transpiling directly to what I want
22:45:53
pjb
vms14: the advantage is instead of having a procedural style, you can have a data driven style, where you have an internal representation of the program you want to generate. So you can manipulate it.
22:49:10
pjb
Instead of hardcoding stuff such as: (php-if (php-equal (php-var "a") (php-integer 0)) (php-function-call (php-function "foo") (php-var "b") (php-integer 42))), you can have some data |# (let ((php-code '(if (= a 0) (foo b 42)))) #| and process it: |# (generate (parse-php-sexp php-code)))
22:50:47
vms14
I had this (defun php-if (test &rest statements) (format nil "if(~a){~{~a~}}" test statements))
22:52:37
vms14
I'll think about writing an AST, because I'd like to learn more about compilers and metaprogramming
22:53:09
pjb
(case (first sexp) ((if) (format …)) ((= /= + - * / …) (format …)) (else #|mustbe funcall|# (format …)))
22:54:47
pjb
Or, you could (defgeneric (op &rest args) (:method ((op (eql if)) &optional then else) …) …)
22:58:11
vms14
the heredocs are because I wanted "" for the html and variable interpolation, but they make the code even uglier
23:22:55
HiRE
could someone provide me a few links of github repos or whatever with really well written modern CL code?
23:23:57
mason
HiRE: There are books worth reading. Here, for example: http://www.gigamonkeys.com/book/
23:24:40
HiRE
thanks Xach. Reason I ask is I'd like to take on a project to write a simple DNS server in CL for my own use.
23:28:01
HiRE
Xach, I'd love to take a look. One thing I was beginning to look at was even how to get started reading/writing packets in CL
23:28:37
pjb
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwjU-KCOn4TnAhWRERQKHcS8Ad0QFjAAegQIAxAB&url=https%3A%2F%2Fgithub.com%2Ffjames86%2Fdragons&usg=AOvVaw15yBgmePwcAl1LunaxgUGy
23:28:38
pjb
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=2ahUKEwjU-KCOn4TnAhWRERQKHcS8Ad0QFjABegQIBxAB&url=https%3A%2F%2Fgithub.com%2Fhanshuebner%2Fans&usg=AOvVaw3Foqv4BPm4Ihcr1iFJB68t
23:28:50
HiRE
mason, that was my initial idea but I'd like to keep it pure CL if possible. I really like CL and FFI seems like a last ditch effort for me.
23:30:12
Xach
*.asd files are input to a program that can compile and load multiple files in the right order
23:31:41
Xach
for typical lisp development you start with a running intractive system and then teach it new things to do
23:32:23
HiRE
oh I see. So instead of having to load a buffer complete in say SLIME you use *.asd to help suggest it stuff?
23:33:15
Xach
HiRE: no. more like someone says "i have a library that does X" and you get that library, the system can use the *.asd file to load that library
23:33:44
Xach
and if that library needs a library that does Y, the *.asd files arranges to load that first too
23:34:32
Xach
quicklisp is a program that handles that error and downloads libraries to make them available to load
23:35:36
HiRE
oh sweet, yeah found the website. Seems like a package manager similar to NPM or something
23:42:06
Xach
i wrote that dns client because i had a web service that fetched images from the web, and i wanted things arranged so that things wouldn't get hung up by DNS or TCP timeouts
23:43:34
HiRE
Xach, I want to write one to help get around the DNS hijacking going on by my ISP lol.
23:44:43
Xach
maybe these things drift offtopic...we can discuss it via private messages if you're inclined.
23:45:19
Xach
i used to work at an ISP, and i know a little about networking, so it is interesting to me.
2:36:46
no-defun-allowed
A lot of things in Common Lisp can have documentation strings, so you probably should be reminded by them in other languages.
2:37:19
no-defun-allowed
To generate a document with all the documentation strings, Staple <https://github.com/Shinmera/staple> could be used.
2:41:33
White_Flame
what's the proper term for a symbol's value binding outside of any dynamic binding scopes? global value, toplevel value, etc?
3:20:37
pjb
"eternal" would be a dynamic (time) notion, but it implies some level of immutability, so it would do only for defconstant…
3:20:51
White_Flame
The length of time is a scope with a definite beginning and usually definite ending
3:21:17
White_Flame
"global" means many things, and the binding in question is the shared one that everybody sees without a local private override
3:21:34
no-defun-allowed
SBCL has a macro named DEFGLOBAL, so there is some precedent to calling it a global value.
3:22:31
pjb
White_Flame: defining a variable with defparameter or defvar doesn't propagate its definition in the past. Therefore it cannot be a "global temporal" scope.
3:23:37
White_Flame
the scope is the distinction between this one and private bindings that other threads of execution create
3:27:29
White_Flame
but I did default to "global" as well, just couldn't find any specific basis for it
3:28:01
HiRE
I think its just the names of the scope. The process is intuitive but "dynamic" goofs me up for some reason.
3:28:32
Bike
the clhs entry for defvar/defparameter calls it the "value cell" but that's kinda bad for other reasons
3:28:37
pjb
If you use the same word for the two orthogonal notion, you are bound to be confused, and to confuse everybody.
3:29:03
White_Flame
and does the "value cell" point to a private location when another dynamic binding is in effect?
3:36:59
White_Flame
" A dynamic variable can be referenced outside the dynamic extent of a form that binds it. Such a variable is sometimes called a ``global variable'' but is still in all respects just a dynamic variable whose binding happens to exist in the global environment rather than in some dynamic environment. "
3:44:22
White_Flame
well, specific to the comment I'm writing, "global value" would imply the value held in symbol's said "global binding", even if there are other dynamic bindings flying around
3:48:22
White_Flame
oh, and "global variable" is in the glossary as well: "global variable n. a dynamic variable or a constant variable."
6:14:29
smokeink
how to muffle such notes? note: doing unsigned word to integer coercion (cost 20) to "<return value>"
7:14:50
White_Flame
I have a macro that generates `(locally (declare ....) ,@body) so I can easily wrap it around small operations
7:15:43
White_Flame
(declare (sb-ext:unmuffle-conditions optimization-note)) around the parameters of the subform also allows its whinings to not be muffled, just the singular form in question
8:41:49
trittweiler
White_Flame, "global binding" versus "thread-local binding" (non-standard, of course) versus "local binding" is decent terminology I would reckon
8:44:48
jackdaniel
isn't the terminology: deep binding and shallow binding (and a symbol value which is not a binding)?
8:46:14
jackdaniel
and a consequence of deep binding implementation technique are thread-local bindings, and shallow gives you bindigns which are shared across threads (n.b probably harder to synchronize )
8:51:17
beach
jackdaniel: The distinction between deep and shallow binding is just an implementation issue.