freenode/#lisp - IRC Chatlog
Search
5:19:16
beach
... and that there are several implementations, free or commercial according to the needs of the project, that implement that standard.
5:19:46
fiddlerwoaroof
Yeah, I really wish more "modern" languages were implemented as compilers to CL
5:20:20
fiddlerwoaroof
ACL2, Shen, etc. show that this is possible and CL is a much nicer target than C or lower-level stuff, if you don't need performance
5:21:10
fiddlerwoaroof
(that is, if you're not in a domain where you need real-time guarantees, etc.
5:21:15
Jachy
That still wouldn't help much though when the younger languages update and make breaking or incompatible changes...
5:21:44
beach
fiddlerwoaroof: There are very few modern "languages", if by "language" you mean an independently published specification of the syntax and semantics of valid phrases, and the consequences of submitting invalid phrases to the compiler.
5:22:46
jackdaniel
Jachy: if your target language of compilation is CL nothing prevents you from putting different language versions in separate packages of the same image
5:23:32
jackdaniel
in that case you'd be able to have (say) python2 and python3 funcitons interoperate
5:23:38
beach
There are, however, plenty of "programming systems" without any attempt at a detailed specification, and certainly no specification of what will remain unchanged in the future and what might change at arbitrary times in arbitrary ways.
5:23:45
Jachy
(Just ran into that last weekend, some code in hip new lang I wrote from 3 years ago didn't run. The language designers put random() into a module.)
5:24:23
Jachy
jackdaniel: by the same logic I can always run an old VM with the old language version, CL as a target not needed.
5:24:47
jackdaniel
Jachy: that's not the same logic, because you don't have two runtimes in the same image
5:25:20
aeth
CL isn't a suitable compilation target for everything that you'd want to have in a language.
5:25:48
jackdaniel
I don't think CL would make a good compilation target, just commenting on Jachy remark
5:27:37
beach
It would probably be a better idea to generate Cleavir ASTs directly from the source language.
5:28:12
beach
A few new ASTs could be introduced where needed, but the bulk of the translation chain would remain the same.
5:28:54
jackdaniel
aren't Cleavir ASTs a subject of the same "beneloved dictator" syndrome you've mentioned before?
5:29:03
beach
That way, you would automatically get source tracking in the source language, and you would not have to debug your code in terms of Common Lisp target code.
5:29:42
beach
jackdaniel: It is not a language, and I don't pretend it is. It is a compiler framework.
5:31:02
jackdaniel
uhm, then why is it better to compile to AST of a single compiler which is designed for another language than to compile to CL which has numerous implementations?
5:31:46
aeth
You could compile to CL by having a series of extensions that the major implementations accepted. beach is right that debugging would be painful, though.
5:32:16
aeth
Afaik there probably aren't *that* many things that couldn't be added as extensions, it's just that it's a niche no one has really catered to.
5:34:20
jackdaniel
I can't be right because I didn't make any statement, just asked a question out of curiosity
5:35:26
fiddlerwoaroof
Racket has done a lot of work to figure out tracking errors in macro expansion to the source the programmer wrote
5:35:46
jackdaniel
compiling to *some* compiler IR is a common thing (LLVM is a common target for instance)
5:40:13
fiddlerwoaroof
I've been writing a lot of Clojure/Scala/Java for $work and not having to explicitly decode/encode values in ffi is the best part of the JVM
5:40:43
aeth
fiddlerwoaroof: notice that JVM languages with the best interop are written specifically for the JVM, though
5:41:15
fiddlerwoaroof
aeth: there's no reason why clojure couldn't be a library + readtable for ABCL
5:42:26
aeth
symbol case sensitivity and a separate nil from false tend to be noticable interoperability issues with other languages and CL
5:43:01
aeth
CL macros would be pretty hard or impossible to interface with from a CLFFI, especially ones like symbol-macrolet
5:44:02
fiddlerwoaroof
I've been doing a lot of work embedding Apple's Objective-C runtime in CL and a couple well-chosen reader macros make dealing with a case-sensitive language pretty painless
5:45:04
fiddlerwoaroof
_using_ macros from other languages would be tricky, but this is true of most of the "advanced" features of JVM languages.
5:48:43
aeth
I've been thinking about Scheme<->CL and I think the best way to handle CL things defined in Scheme is to assume CL is being written case-insensitively with automatic upcasing and downcase it. So if you define a Scheme CONS from CL, turn it into |cons| because it was probably written as cons and then upcased into CONS.
5:49:40
aeth
Going the other way could be trickier. You could just upcase |foo| into FOO but the Scheme could be written with case-sensitivity in mind.
5:51:24
fiddlerwoaroof
https://bitbucket.org/cowan/r7rs-wg1-infra/src/312606b342ba83fd099cc5719ae71fc9ada1890a/RedEdition.md?fileviewer=file-view-default
5:55:17
Jachy
fiddlerwoaroof: If it's so simple for objectitve-c I'm curious why ABCL and then later JSS lib still use strings to identify java method names...
5:55:29
aeth
e.g. doesn't look like this is a SRFI https://bitbucket.org/cowan/r7rs-wg1-infra/src/312606b342ba83fd099cc5719ae71fc9ada1890a/WG1Ballot8.md?at=default&fileviewer=file-view-default
5:59:48
fiddlerwoaroof
Objective-c does have the advantage that it's designed to be embedded into another language
6:00:42
fiddlerwoaroof
https://github.com/fiddlerwoaroof/objc-lisp-bridge#type-directed-objective-c-extractors
6:01:04
aeth
I could probably do Scheme via a reader macro because once there's a reader you just plug the reader into the reader macro
6:01:20
fiddlerwoaroof
I'm planning to eventually get rid of having to specify the type of each argument
9:31:39
zigpaw
nicely looking and there are great suggestions in the hackernews thread, lots of links I have tried on the projects sub-page doesn't work unfortunately.
9:52:47
jmercouris
Ok, I just checked the irclog link instead of the CCL one, seems the CCL one is not up- to date
9:53:03
jmercouris
There was some user who said something along the lines of using generic functions in scheme or something
9:54:15
jmercouris
this is the log I was looking at: https://gist.github.com/jmercouris/e04f787e088f9f3a14923077bbecbad5
9:54:51
jmercouris
and it seems that it was some time ago, as that is the end of log available on http://ccl.clozure.com/irc-logs/lisp/ for 2018-10-12
9:56:06
jmercouris
It seems like the more likely explanation now, people don't tend to use the word generic that often :D
9:56:27
jmercouris
I happen to have a freind who overuses that word, so maybe I am seeing things where they are not
9:57:41
jmercouris
that is something I do wonder about, what is the purpose of defgenric when defmethod will implicitly make a defgeneric?
9:58:38
beach
There is also some default given to your &key, &rest, and &allow-other keys that might be preferable to give explicitly.
9:59:11
jmercouris
What do you mean by that last part "you get to give your preferred method combination"?
10:02:36
beach
Here: http://www.lispworks.com/documentation/HyperSpec/Body/07_ffd.htm is a list of the built-in method combinations, but you can also define your own.
10:02:38
jmercouris
so why might you want to use :method to define a method against a generic function instead of doing it in a separate form?
10:03:35
beach
If you methods are trivial, like (defgeneric consp (thing) (:method (object) nil) (:method ((object cons)) t))
10:05:58
beach
Here https://github.com/robert-strandh/Eclector/blob/master/code/reader/generic-functions.lisp are some examples.
10:07:11
jmercouris
And in that case, I might naturally ask the question, why not forgo the defgeneric altogether?
10:09:42
beach
Here: https://github.com/robert-strandh/SICL/blob/master/Code/Cleavir/Input-output/io.lisp you have an example of the APPEND method combination.
10:10:08
beach
jmercouris: Because you may want to allow for the client to override the methods, or to provide auxiliary methods.
10:10:56
beach
jmercouris: In the example, the client is T. Typically, client code will define its own CLIENT object, and then override the default method.
10:11:23
beach
Or, if they are happy with the default action, they just don't define an auxiliary method.
10:11:48
beach
jmercouris: This is the very basis of programming with generic functions, allowing client code to adapt the way the module works.
10:12:30
beach
jmercouris: I guess your experience with object-oriented programming is from a language that does not use generic functions.
10:13:39
beach
But they are probably all based on the same principles, which are different from those of CLOS.
10:14:37
jmercouris
mostly because I made too many assumptions about that snippet of code, I assumed it was internal
10:14:46
beach
In all the other languages you know, client code would make a subclass and override that way.
10:15:16
jmercouris
In this case they would just specialize on the appropriate set of classes, right?
10:15:22
beach
No, that was the very client interface of Eclector, allowing client code to customize its behavior.
10:15:37
jmercouris
so they just need to write some new defmethods with the appropriate lambda lists, and they can change the behavior
10:18:16
jmercouris
That's what I've gathered as well, and on some intellectual level, I understand some of the details, and how it works, but I haven't really internalized it, and my thinking is still shaped for a traditional model
10:18:40
jmercouris
many years of java training has done me in, but I'm slowly changing my ideas about programming, I understand the process of "de-doctrination" takes time
10:19:24
jmercouris
I know for sure other parts of my mind have changed with regards to how I think about programming as a result of lisp, but I just haven't gotten deep enough into CLOS yet, to get that same effect
10:24:02
Jach[m]
jmercouris: I've only recently cracked open "Object Oriented Programming: The CLOS Perspective" and finding it helpful (plus the hardcover has nice cover art...)
10:24:48
jmercouris
Jach[m]: I'm in the middle of gentle introduction to common lisp, maybe when I'm through with that I can take a look, thanks for the suggestion
10:35:04
jmercouris
that's why I start with a gentle introduction to common lisp, now that I've been doing lisp for a while, it sticks a little easier
10:35:34
jmercouris
PCL is indeed practical and succinct, and as a consequence, not really memorable, at least for me
10:36:32
beach
ACTION needs to remind his favorite coauthor about the many book projects we need to work on.
10:37:03
heisig
In my experience, the best way to learn and understand CLOS is to read other people's code. Some code that comes to mind is cl-dot, cl-graph, Eclector (and pretty much all of SICL), ASDF and maybe LIL.
10:37:58
heisig
But yes, the world would benefit a lot from a book on CLOS that is more practically oriented than AMOP.
10:38:35
beach
... and with better and more examples than "Object-Oriented Programming in Common Lisp" by Sonja Keene.
10:48:22
beach
I didn't like the examples. One example was about software distribution for different platforms, which doesn't speak to someone who is that new with object-oriented programming. Another example was about threads, which are not in the standard. The entire thing gave me the impression that there are few examples where object-oriented programming is useful, since it must be hard to come up with more mundane examples.
10:52:34
no-defun-allowed
Indeed it is. The rest of the book is nice but the examples (except the spam filter, that's a masterpiece) were fairly underwhelming.
10:54:55
shka_
beach: i started a blog, i will describe my last discussion with phoe regarding message/answer representation next
10:54:57
no-defun-allowed
If it were, I imagine the plet* system would do some tree generation and figure out which bindings to evaluate next while they were being evaluated.
10:57:14
no-defun-allowed
I'd just want to make the second "required" list automagically generated, which seems fairly trivial.
10:59:53
no-defun-allowed
It'd just be the variables in the value form that are in the previous bindings.
11:04:24
scymtym
finding free variable occurrences in a form generally requires code walking. if the names of the variables in questions are known (like in this case) a hack like (catch 'occurs (sb-cltl2:macroexpand-all '(macrolet ((occurs () (throw 'occurs t))) (symbol-macrolet ((VAR (occurs))) FORM))) nil) can work
11:15:34
no-defun-allowed
Code walking is very simple though. I also have a set of variables I'm only interested in too.
11:39:08
jcowan
as for predicate-based generic functions, since I am a spec writer and not (with this hat on) an implementer, I don't have to provide an efficient implementation. Lots of things in JavaScript, e.g., weren't known to be efficiently implementable when they were first specified, but nowadays fast JavaScript is a thing.
11:41:59
no-defun-allowed
scymtym: I guess it isn't as simple with macros and the like. I'd assume that the plet* forms would not cause side effects and would be "functional" to some extent.
11:42:38
ggole
Expecting something to be fast just because it would be convenient if it were fast is a good way to get a slow thing
11:46:22
scymtym
no-defun-allowed: even without macros, the analysis has to be aware of all special operators and has to keep track of lexical variables
11:55:10
pfdietz
The specified evaluation order of CL forms is a wonderful thing, compared to (say) C.
11:59:43
pfdietz
I think the poor choice was driven by how restricted C compilers were on 16 bit platforms. Tiny, tiny things they were.
12:03:57
heisig
A consequence of the unspecified evaluation order is that I consider every C and Scheme program broken unless proven otherwise.
12:04:37
heisig
I also consider every program broken that uses fixed size integers without proving rigorous upper bounds :)
12:05:38
ggole
It may have been beneficial for early compilers with weaker approaches to optimisation
12:07:39
pfdietz
jackdaniel: I can show you a perfectly correct seven line CL program that causes the SBCL compiler to blow out memory due to bignum sizes (and would not overflow if just run naively). The problem does come up!
12:07:49
heisig
jackdaniel: In this case, stopping because of heap exhaustion is the only sane option. Would you prefer your program to continue despite being broken?
12:09:40
jackdaniel
heisig: my point is that if you don't control upper bounds your program may not return correct results (because it won't return results at all!), having fixed size integers and crash on overflow is equally good/bad
12:10:37
jackdaniel
I'm of course half joking (like you did with demanding proofs of program correctness :)
12:10:52
pfdietz
In this case, it would have been possible for the program (the compiler) to succeed, just by giving up and widening the inferred types to (INTEGER * *).
12:13:06
heisig
jackdaniel: Oh, sure, if your languages crashes on overflow that is still sane (and might be preferable for real-time systems).
12:14:24
heisig
... for real-time applications. For a computer algebra system, I would be quite bothered by that.
12:16:01
pfdietz
Speaking as a compiler tester, I really like that in CL integers behave like integers. It makes it easier to write test generators. Doing the same on C was hard enough that Regehr's team got several papers out of it.
12:16:59
pfdietz
Avoiding the 100+ (?) undefined behaviors of C while generating and simplifying tests is difficult.
14:05:20
pfdietz
I vaguely recall the original C standard was influenced by the existence of the Symbolics C compiler, which if I recall correctly translated C to Common Lisp.
14:05:48
foom
no, everyone agrees that no 1s complement platforms exist anymore. The undefined-behavior is there, now, for 2 reasons:
14:06:00
semz
if it's undefined behavior, the compiler may assume it doesn't occur, which allows a few optimizations. regehr had some posts about this
14:06:01
foom
1) the compiler/runtime may detect and abort upon seeing it, instead of being required to wrap. But wrapping is almost never what users _really_ wanted.
14:08:05
pfdietz
I'm not sure detecting and aborting when going out of bounds is wanted either. Look at the first Ariane 5 (failed) launch (Ada there, not C though).
14:09:06
pfdietz
The problem was in pre-launch calibration code. It did not matter what it was computing at that point.
14:10:12
pfdietz
The code was left over from Ariane 4. But Ariane 5 leaps off the bad much faster, so a number overflowed.
14:10:42
jackdaniel
in ideal world of fixed integers (without possibility to upgrade to bignums) would be: a) signalling a condition; b) having condition handlers like in CL; c) compiler giving warnings (or errors) if there is no proper handler for the operation which may overflow - that's at least my not well thought-through opinion for this moment :)
14:13:25
semz
considering how arithmetic without error handling is impossible this seems like The Right Thing (tm), but the question is how to do it a) efficiently and b) with clean code
14:14:35
semz
(a) might be easier because the handlers will probably do some cleanup nearby, so the compiler could recognize it
14:14:38
jackdaniel
I find Common Lisp condition system one of its most amazing features (and it is fairly clean and efficient)
14:14:53
ggole
Seems the ariane 5 thing was a conversion from a double to uint16, rather than a uint16 operation overflowing
14:17:07
semz
since it's borderline impossible to write C which handles all overflow conditions and not end up with a hairball
14:22:52
jackdaniel
heisig: not so much for embedded boards like arduino, but these lose in importance every day - it becomes cheaper to standarize on arm than on atmega even for home electronics
14:23:17
ogamita
ggole: (defun speed (a dt s) (+ (* a dt) s)) (speed (the (unsigned-byte 16) 42) 3 0) #| --> 126 |# (speed (the double-float 42.0d0) 3 0) #| --> 126.0D0 |#
14:25:28
heisig
For modern systems, Common Lisp is almost always a good choice. Even for system programming. I recently played a game of Quake on an operating system written in Common Lisp :-)
14:25:46
ogamita
(declaim (optimize (space 3) (speed 3) (debug 0) (safety 0))) (defun new-speed (a dt s) (declare (type (unsigned-byte 16) a dt s)) (+ (* a dt) s)) (new-speed 42.0d0 3.0d0 0.0d0) #| --> -4210554732912278340 |# !!!
14:28:21
jdz
ogamita: you first tell SBCL to not check your values, and then you complain that it does not do what you told it to do?
14:29:08
ogamita
You choose to write programs in C and then you can't complain when your rocket explodes…
14:31:36
ogamita
Shinmera: there's still a choice by sbcl implementors to allow wrong results with safety 0…
14:31:59
ogamita
Similar to C implementors. So they indulge to the same mindset and allow it to develop with sbcl…
14:33:14
ogamita
The spec also allows array-total-size-limit to be 1024, sbcl implementors still set it to a higher value…
14:33:19
jdz
ogamita: (sb-ext:restrict-compiler-policy 'safety 1) and you will live happily ever after.
14:49:44
shelvick
Has anyone run into this problem before with ironclad or nibbles? https://pastebin.com/bTVL8FNs
14:53:45
beach
semz: I am convinced that if you just add a few primitives to your Common Lisp implementation, then it becomes a perfect fit for system programming.
14:54:39
pfdietz
shelvick: nibbles uses internal SBCL things that change frequently, so don't expect recent versions to work with old SBCLs.
14:57:45
semz
embedded and kernel stuff, primarily. though admittedly the main motivation was more of a vague "let me get rid of C and its nonsense already"
14:59:27
beach
semz: Well, clearly full Common Lisp is probably too big for many embedded applications.
15:00:24
beach
semz: I am guessing you mean applications that must manipulate arbitrary addresses in arbitrary ways. In those cases, I think system programs written in C probably rely a lot on undefined behavior.
15:02:24
beach
semz: On the other hand, if we abandoned the silly (and very old) idea that an application program should have access to the full address space (including the stack) as if it had access to a raw computer, then we could write a very safe operating system using Common Lisp. But it would not have a "kernel" in the Unix sense of the term.