freenode/#lisp - IRC Chatlog
Search
3:28:12
asarch
Two questions: How is π (in C it is M_PI) and what is the shorter form for r^2 (* r r)?
3:42:06
asarch
One very very stupid off-question: can you use the full of Maxima with only Common Lisp?
3:43:38
beach
asarch: Though, check out Climaxima that loke has been working so hard on. It uses McCLIM (which is written in Common Lisp) for its rendering.
4:01:05
nitrix
Hello. I've been reading a lot about Lisp and the various dialects lately (I even got my copy of SICP). I'm really loving the whole minimal syntax, homoiconic, the ability to build the language bottom-up and give/change the meaning of any symbol, including the evaluation itself (in the case of macros).
4:02:27
nitrix
I feel like I'm getting closer to some kind of nirvana, but somehow the memory aliasing / mutation / GC parts of most of these dialects still feels very dirty to me.
4:05:09
no-defun-allowed
Not sure what memory aliasing is, but you need GC for closures from memory.
4:07:14
nitrix
I suppose my biggest problem is the ability for two symbols to share the same "storage"; as in mutating one affects the other.
4:08:15
nitrix
In C, this would having two pointers with the same value, thus both pointing at the same memory location.
4:09:18
nitrix
no-defun-allowed, not sure where the term originates from but the C community refers to it as aliasing memory.
4:10:29
nitrix
Correct. The problem is as soon as you do that, you more or less lose closures, don't you?
4:12:25
nitrix
Like, the only semantics that makes sense from lambda if you take that route is for (lambda (x) (y)) to capture the value of y by coping it.
4:12:40
LdBeth
Closure is mainly for variable capture, and the only reason to capture variable is to update it
4:13:39
nitrix
I can think of a second use, which would be creating partial applied functions (if you're familiar with some functional programming concepts)
4:16:20
nitrix
I'm starting to think my desire for immutability comes from not having a clear understanding of symbols and their evaluation.
4:17:52
beach
nitrix: If you are looking for immutability, Common Lisp (which is the subject of this channel) is not for you. I suggest you look at some functional programming language instead. Common Lisp is a multi-paradigm language, and modern Common Lisp uses object-oriented programming (using CLOS generic functions) a lot.
4:19:54
nitrix
beach: In all honesty, I do not have a strong preference between mutability or immutability on a day-to-day basis. I think I'm more trying to understand the implications of both for someone developing a dialect or wanting to adopt an existing one.
4:21:20
beach
nitrix: Like I said, this channel is dedicated to Common Lisp, so we don't much discuss other dialects (existing or new ones), other than if a compiler for such a dialect were to be written in Common Lisp.
4:21:21
nitrix
beach, suppose I have the symbols x and y. Does Common Lisp or some other lisp, allows for x to become some sort of entangled with y such that incrementing the value of one increments the other?
4:21:46
nitrix
Let's take Common Lisp then since it's the most popular and probably where I should start :)
4:21:57
beach
nitrix: That would not be possible, but you can have symbol macros that might make it look like that.
4:23:17
nitrix
Oh interesting. That would require a small change in usage though, no? Like (x) for the macro to expand to whatever pointer chasing it needs to do?
4:24:54
beach
nitrix: The evaluator simply replaces the reference to *y* with a reference to *x* and evaluates the replacement instead.
4:25:03
nitrix
I see. So define-symbol-macro's purpose seems to be precisely to modify what happens during the evaluation of a given symbol.
4:26:19
aeth
If you want immutability, defstruct has :read-only slots so you could just make every slot read-only. It absolutely will *not* be efficient, though, because no one writes this way so no implementation optimizes this.
4:26:41
nitrix
Okay, but you see, this is already a really big piece to me. That means that, unless you meddle with macros, symbols are consistent.
4:27:05
nitrix
As in, you assign them a value and it's just a mapping in the environment from the name to its designated value and that's it.
4:27:55
beach
nitrix: Here are the evaluation rules for Common Lisp: http://www.lispworks.com/documentation/HyperSpec/Body/03_aba.htm
4:28:11
pjb
nitrix: notice that the homoiconicity in scheme is remote. You have to use special operators to convert syntax objects into sexps and vice-versa in scheme macros.
4:28:31
pjb
nitrix: I would say that scheme doesn't have a pure homoiconicity. Only the other lisp have it.
4:28:58
aeth
pjb: I think you mean portable Scheme, nothing stops Schemes from having defmacro (or define-macro)
4:29:54
nitrix
beach, I'm sure that's an invaluable reference and I bookmarked it for later. Sadly, it's not very useful to me as I lack the foundation necessary to make sense of it.
4:30:35
beach
nitrix: If you want to learn more about Common Lisp, I recommend #clschool for newbie questions.
4:31:13
beach
nitrix: Again, your model is too simplistic. Common Lisp typically compiles to native code, and symbols that designate lexical variables no longer exist at run time.
4:31:44
pjb
nitrix: aliasing poses no problem in lisp and languages where similarly the values are typed, not the variables. The problem with aliasing in C, is that the two identical pointers can be stored in variables of different pointer types. Otherwise, having two references to the same object can only pose a problem in multi-threaded applications, if you don't take care to synchronize accesses.
4:33:37
aeth
nitrix: a symbol itself is essentially a pointer... but what it points to isn't really important, it could just as easily be a number (but then that would complicate accessing symbol-associated things like its symbol-plist, etc.)
4:34:43
pjb
Even if your CL implementation doesn't have a native or byte-code compiler, it still has to implement minimal compilation, which includes macroexpansion and taking note of special declarations.
4:35:56
aeth
pjb: 'foo is in my brain 2578394... Well, actually it's probably #xff34e34 or whatever since it's probably a pointer, but that's a detail
4:36:19
nitrix
So, conceptually at least, it's associative, right? There's an association between a symbol (its name) and some value. Evaluating the symbol resolves to that value.
4:40:41
pjb
nitrix: you're asking a scheme question here. Better ask in #scheme or ##lisp (for comparative lisp).
4:41:39
pjb
nitrix: in Common Lisp, arguments are passed by value. So the function doesn't know that the value it receives comes from a variable or from an expressiosn.
4:41:40
LdBeth
nitrix: unless n is a boxed value such a a cons, passing n to a function won’t mutate it
4:42:07
pjb
nitrix: most lisp values are mutable. Only the numbers and the characters are immutable.
4:42:26
nitrix
I'm asking because even though `foo` has two parameters, `x` and `y`, the function was called with the same `n` argument twice, so I'm wondering if the two "names" starts sharing the same value now.
4:42:29
aeth
You probably meant something like this? (defvar *n* 42) (defun foo (x y) (setf x 7) (values x y)) (foo *n* *n*)
4:43:31
pjb
nitrix: and aeth assumes one meaning of your expression "foo starts mutation x" which is not English, and is not clear. Do you want to mutate the parameter X, or do you want to mutate the value bound to the parameter X?
4:44:16
aeth
nitrix: You could think of it like a series of hash tables, where if it's not in the most local hash table, it looks up one level, and then up one level, etc.
4:44:33
nitrix
pjb, Well, that's where it becomes interesting because I didn't know there was a distinction between both. C has that distinction, I didn't know CL did too.
4:44:35
pjb
(defparameter *n* (list 42)) (defun foo (x y) (setf (car x) 33) (list x y)) (list *n* (foo *n* *n*) *n*) #| --> (#1=(33) (#1# #1#) #1#) |#
4:45:39
nitrix
pjb, So mutating the parameter X would be observed only locally, by binding a new value to it, but mutating the value bound to the parameter X would have a bigger implications because Y uses that too?
4:45:45
aeth
pjb: See what I wrote in #scheme not very long ago to see how I disagree with you about C behing higher level than Lisp
4:46:19
pjb
aeth: we're talking about informal notions here. You can take all informal statements to #lispcafe.
4:47:03
pjb
aeth: I say C is higher level because of how it specifies pointers, memory, and foremost, bit manipulation. You must manipulate bits in C using integer operations (very abstractly). In CL we have bit operators.
4:47:12
aeth
nitrix: What's fun is that CL has 0-dimensional arrays. (make-array '() :initial-element 42)
4:47:36
aeth
nitrix: So if you wanted to modify some global integer in the simplest way you could just put it in a 0 dimensional array
4:48:08
nitrix
aeth, I'm not especially interested by global anything as they tend to be treated differently.
4:48:25
oni-on-ion
there are more things "behind the scenes" happening with lisp. that is most people's intuitive understanding of what is "higher level" (like super-natural)
4:49:48
aeth
nitrix: You can compare the two items in this list: (list (let ((x (make-array '() :initial-element 42))) (let ((x x)) (setf x 43)) x) (let ((x (make-array '() :initial-element 42))) (let ((x x)) (setf (aref x) 43)) x))
4:49:52
nitrix
pjb: How would I rebind a new value to X, versus, mutating the value that's bound to X?
4:50:37
LdBeth
nitrix: then the book “interpreting lisp” has cover most aspects, please try read then ask questions
4:51:23
pjb
nitrix: in the case of symbols, you can use the name for special variables. defvar and defparameter declare special variables. You can also declare temporary special variables.
4:51:35
aeth
nitrix: The easiest way to get something like &foo where foo is an int is to put it in a 0D array as I said.
4:52:42
nitrix
aeth, but that'd mean that CL uses pass-by-value where the values are sometimes pointers for specific types (like arrays) and you're exploiting that to obtain the pointer effect.
4:53:09
oni-on-ion
are we teaching how to do C-stuff in lisp ? what if we dont need to do those things in lisp....?
4:53:28
aeth
nitrix: you could think of it as *always* passing in pointers, it's just that if it's a pointer to a constant value 42 that fits in a word including its type tag, it gets optimized away
4:53:50
pjb
nitrix: the problem is that as indicated in the /topic, Common Lisp is the #1=(programmable . #1#) programming language.
4:54:27
aeth
oni-on-ion: I mean yesterday someone said that C++'s hello world was the ugliest so I implemented it in CL.
4:54:39
pjb
nitrix: also notice how I said that C was a botched derivative of lisp (like most other current programming language).
4:54:52
pjb
nitrix: this means that you can do anything those languages can do, rather trivially in lisp.
4:55:43
oni-on-ion
=)... well also, we can provide a little guidance to the lisp way of things, if applicable. certainly we can do shaolin kung defu, but what is the practical way to walk on spears?
4:56:50
pjb
If you look for a language that goes a little beyond lisp, you could take Haskell. Even prolog is completely embeddable trivially in lisp.
4:57:18
aeth
pjb: eh, a while back someone who was working on a Prolog said that prolog isn't easily embeddable in Common Lisp
4:59:07
nitrix
Also, I'll be the own judge of whether or not my questions makes sense. I understand what I'm asking isn't specifically Common Lisp, but it's not like I'm against it either. I'm glad to hear how CL does things and if I can make sense of it, I'll definitely get behind it. For now, I have to understand it first instead of being sent to ##lisp and dismissed.
4:59:11
oni-on-ion
its just that CL makes 40mb exes. wonder whats in there that C doesnt have ? lisp still links to all the same libs, too. strange!
4:59:43
LdBeth
nitrix: that’s even good, because I’ve looked tons of Haskell projects teaches how to write a lisp
4:59:43
pjb
C executables link with a 20 MB libc, which is about the same size as the libecl library.
5:00:13
pjb
So you can either use an image based system, and have your library "statically linked" or you can use ecl, and libecl.so.
5:00:21
aeth
pjb: no, I mean, there are apparently some well-known obstacles for efficiently embedding Prologs within other languages, and someone here a while back was talking about those
5:00:48
aeth
I am not an expert in Prolog implementing (I've barely been exposed to Prolog) so I won't claim to know exactly the issues were...
5:01:02
pjb
oni-on-ion: we could implement the syscall ABI in CL implementations and do entirely without libc.
5:01:03
oni-on-ion
the least amount of baggage is pure assembly of course, then next slimmest-to-system closest-to-metal is C.
5:01:59
nitrix
LdBeth: Choosing the semantics is the hard part. I want to better understand the choices behind CL and their implications.
5:02:14
oni-on-ion
i think linux abi has been stable for a while. windows 10 64bit ships with binary compat (WSL)
5:02:25
pjb
aeth: of course, this is work to maintain the syscall ABI on all target platforms. Hence we defer to libc maintainers…
5:02:54
aeth
oni-on-ion: Linux syscalls are stable, is what I mean. They're treated as an external API. Syscalls to e.g. NT are treated as an internal API
5:03:19
LdBeth
nitrix: there’s not much semantic difference between CL and Scheme, except for continuation part
5:04:35
nitrix
Alright. Thanks for the help. Tiny progress was made but it quickly turned into chaos. I'll give it a try another day.
5:05:04
aeth
LdBeth: If CL implementations had an API that said "force TCO" and an API that exposed some form of continuations, you could basically just do a bunch of syntax macros and trivially do a Scheme in CL afaik
5:05:28
aeth
LdBeth: The continuations can't be as full as in Scheme because of the conditions system in CL afaik, but they could probably be complete enough to run a Scheme runtime in a CL runtime
5:06:00
pjb
LdBeth: only it's very difficult to have both continunations and block/return catch/throw.
5:06:30
oni-on-ion
okay i wasnt sure -- i heard a lot about the debates between scheme and CL about #f/nil/()/etc. BUT!! i swear i've seen a lisp file once, that was compilable on three different lisps. scheme, elisp and CL i think.
5:06:40
aeth
pjb: But you could probably make it happen if the continuations were for embeddable languages like Scheme rather than for the entire CL runtime
5:07:08
LdBeth
pjb: I believe Chez has accomplished that by means of lexical continuation and dynamic continuation
5:07:41
pjb
aeth: yes. However one point of embedding a language in the other is to be able to mix them rather freely. Calling CL from scheme and calling scheme from CL.
5:08:36
aeth
pjb: Yes, which means you now have two wrappers of Scheme-in-CL functions, one for procedures and one for predicates. predicates return t/nil which become #t/#f, where #f is some symbol that's not nil. Regular procedures assume nil is '()
5:09:21
oni-on-ion
my conclusion is that the true ultimate computer language is simply binary and ascii. everything else is a subset
5:09:29
aeth
And, if you really wanted to, calling Scheme from CL could just always turn #f into nil
5:10:09
aeth
LdBeth: The point is that there should only be one runtime for managed (i.e. GCed) languages because interoperating between multiple GCed languages is messy
5:10:39
aeth
LdBeth: The other point is that SBCL is pretty fast, so you might get, for free(*), one of the fastest, if not the fastest, Scheme implementations (* not really free, see continuations)
5:11:39
aeth
Well, actually, I can't really wait on them, since what everyone's waiting on here is my code.
5:13:34
LdBeth
I mean CL and Scheme is still close enough to interpolate with only the help of macro
5:16:24
pjb
And yes, those questions (efficiency, calling one language from another, etc), are actually old questions. Nowadays, we have fast processors, gigabytes of RAM, even faster multi-core GPUs, and the internet providing us with more libraries than we can use. There's little reason to try to use a library from a foreign language anymore.
5:17:05
pjb
In the 80s, it could have been a good idea to embed scheme or prolog in lisp to re-use their code. Nowadays, we probably already have two CL libraries doing the same.
5:17:11
oni-on-ion
'from a foreign language' ? do you mean using a foreign language to access, or accessing the library *in* a foreign lang?
5:18:06
oni-on-ion
on one side i had started using C for the lib that talks to all the C libs, then i noticed my high level language file doing the same thing with ffi was 1/3 the size
5:18:08
pjb
The later option is preferable (and started implementing a C->CL compiler to do that with GNU emacs), but note that we already have Hemlock.
5:19:23
pjb
Then we can write our own emacs extensions in CL, but we keep using the GNU emacs maintainers' work and third party emacs lisp code.
5:20:10
oni-on-ion
i'd rather write in elisp =) there isnt much lacking that CL would bring to the table, aside from performance and even longer identifiers
5:50:23
pjb
oni-on-ion: it was actually better without asdf and quicklisp: you had to locate lisp code, download it, read it to learn how to load it. You would write a loader script if there wasn't one. You would enter into it and learn more than nowadays. Nowadays, you just quickload a system, and call one or two functions in it, and that's it. You don't learn anything.
5:51:37
oni-on-ion
pjb, hmm, true! that sounds like its close to how nice smalltalk felt with ChangeSets
5:56:34
oni-on-ion
i think ive still got some of the webserver code that i used defsystem with, around 2011
5:57:12
oni-on-ion
im reflecting on whether these conveniences are perverting the pristine shimmering purity of CL
5:59:53
no-defun-allowed
in this case, not cause it'd be bad, but it's probably not as good as ASDF or a de-facto standard
6:06:19
no-defun-allowed
That makes perfect sense, since CL obviously compiles to .o files and can be linked and assembled just like a C program.
6:07:55
aeth
if you don't have a CL daemon that takes stdin from the shell just so you can load libraries via makefiles and bash, you don't know what you're missing
6:10:54
stylewarning
"The problem with defending the purity of Common Lisp is that CL is about as pure as a cribhouse whore. We don't just borrow paradigms; on occasion, CL has pursued other languages down alleyways to beat them unconscious and rifle their pockets for new functions."
6:25:14
Nilby
Indeed, I spent part of today rifling through the pockets of code in other languages, just to "borrow" them for CL.
6:32:47
Nilby
In this I pilferd Clojure's group-by, which was probably implemented in Lisp before Lisp was.
6:49:23
no-defun-allowed
well we don't intend to give them back so is it borrowing? also, they still have it too
6:50:50
shka_
anyway, assimilating foreign ideas in programming is arguably more powerful then coming up with your own
6:51:33
no-defun-allowed
if it's anything CLOS and the MOP, it's assimilating foreign ideas and abstracting and extending them to the extent it's basically new
8:51:20
aeth
The only valid CL style is to have a separate foo.h.lisp for every foo.lisp and in that file do stuff like (declaim (ftype (function ((unsigned-byte 32) (signed-byte 32)) (values (signed-byte 32))) foobar))
9:17:13
aeth
saturn2: I already did that... https://gitlab.com/zombie-raptor/zombie-raptor/blob/41e9e6553a83015d67e14aad5b46f60dcf40b862/util/types.lisp
9:39:01
aeth
I guess a hypothetical foo.h.lisp would be the worst of both package.lisp and package-at-the-top styles
10:01:54
aeth
That wouldn't work because we export symbols, not functions. Well, it would work, just with some unexpected edge cases.
10:04:41
asdf_asdf_asdf
Hi. [SBCL] http://www.sbcl.org/manual/ How using sb-alien... write equivalent to "void*"? I try: "(define-alien-type (* void))". Doesn't works.
10:53:05
schweers
asdf_asdf_asdf: maybe just (*)? anyway, is there a reason you’re using sb-alien instead of CFFI? or some ohter portablility layer?
10:53:27
shka_
https://github.com/numcl/numcl this got my interest, it looks pretty good on the surface, what do you guy thinks?
10:59:30
asdf_asdf_asdf
Manual: The foreign type specifier (* foo) describes a pointer to an object of type foo. A pointed-to type foo of t indicates a pointer to anything, similar to void * in ANSI C. A null alien pointer can be detected with the sb-alien:null-alien function.
11:09:22
pjb
aeth: now of course, nothing prevents you to defined a module abstraction, where you could declare that you'd export from the module either the function or the variable or the type, or whatever else kind of binding, and when you import the module, you'd get only that. That would be independent from packages…
11:28:15
schweers
has anyone here used the code coverage facility of CCL? I set ccl:*compile-code-coverage* to t, recompiled my sources and ran the tests. So far so good. When I run CCL:REPORT-COVERAGE, I get an error which claims that NIL is not of the expected type STRUCTURE.
13:02:05
pfdietz
stylewarning: that quote was originally by James Nicoll, and it was about English, not Common Lisp. https://en.wikiquote.org/wiki/James_Nicoll
13:39:47
asdf_asdf_asdf
In manual: http://www.sbcl.org/manual/ is (slot ...). I want pass function WindowProc as alien-type-function. How it do?