freenode/#lisp - IRC Chatlog
Search
4:33:18
beach
jeosol: It is not reserved for Europeans. We have many participants from all over the world. US in particular, but also Japan and some other places.
4:34:48
jeosol
I have finished my challenge code so I am fully in invested in CL for now. I am planning to start presenting my work soon.
4:34:50
beach
Usually, you can wait until much later, but this time ELS is held jointly with the <programming> conference, so there will be many people who need rooms.
4:36:04
jeosol
I would never have been able to do it without CL. For example, the macro facility was exception and of CLOS which my codes uses a lot.
4:36:47
jeosol
also look forward to get jobs where I can hack CL. I almost got one with some US defense guys, but security clearance issues.
4:37:03
jeosol
thanks for the link. I will look it up and start making plans. These things go by quickly.
4:37:37
jeosol
But then, I will need EU work visa right? I will be in Barcelona for the Challenge conference, so I may try to see if I can visit them.
4:42:03
rme
I understand that Spain can be rather troublesome, but why not talk to RavenPack anyway?
4:42:09
beach
jeosol: I know of at least 5 US-of-Asians who, once installed in the EU never looked back.
4:43:59
beach
rme: Oh? That would be very surprising. Sure, if you are an unskilled person from Africa, I can imagine a few obstacles, but if you have an offer of a skilled job, I don't see the problem. But maybe you know better than I do.
4:47:30
jeosol
I normally joke that "blessed is S/he who hacks lisp for a living ...". There are a few companies there have adverstise and look for CL as part of their stack, but then they want other languages too JS, Java,...
4:47:55
jeosol
that's good actually. I will start developing some contact. Conference is in September
4:48:17
aeth
jeosol: If you have European ancestors you might actually be able to get European citizenship. Depends on the country. Italy is the easiest.
4:48:56
rme
beach: I can't quite make a move to Bordeaux (or anywhere in France) work out just on my own. I'm talking to some potential employers, though.
4:50:51
beach
jeosol: The great advantage of going to ELS is that you will be able to put a face on many of the #lisp participants.
4:51:13
aeth
Personally, I think I could get Italian (1/4) or Hungarian (1/16??) citizenship if I tried. For the latter I would have to learn Hungarian, though.
4:55:26
jeosol
beach: yes, good point. Nothing like meeting people and discussing in person and finding common grounds and collaborative projects.
4:56:24
jeosol
I did plan to come this here, write my paper on building a very large project/application with CL.
4:57:17
jeosol
when I started, my code was barely running stable, issues, but after questions here and comp.lang.lisp, it is running smoothly, and runs for days and weeks without issues now.
4:58:31
jeosol
beach: on the conference bit, I think the collaboration is something that would be useful. For example, I have talked about picking up CLML for machine learning/AI but waiting to sort out the licence issues and get a go-ahead
5:01:05
aeth
I cannot easily break 10k. Every time it looks like I might get close, a new macro pops up.
5:01:59
jeosol
There are a few reasons for the productivity, lisp being one of them. I type fast, and because I can reach any file and function from within emacs, all those things help. Also, my code is essentially a document because I use long
5:02:49
jeosol
variable names which my be hard for many. The variable names and function names convey meanings. So with the code reading like a document, it was much easier to write along.
5:04:01
jeosol
I won't recommend writing it the way I did, I was also writing to code as a hobby (April 2016), then a challenge came up Feb 2017, so I decided to make the code be able to solve that challenge. Deadling was a month ago.
5:05:01
jeosol
But I must say, I have enjoyed working on the project and can't imagine if I can get to code CL and get paid for it. hmmm
5:06:46
jeosol
but one thing I would say is that, my code quality gets better with time. When I learnt the basic things I needed, I just started writing and replacing code as I go forward and using better idioms, or techniques to improve efficiency. But my focus was
5:09:18
jeosol
I would say it is a platform because the code base contains optimization engine, statistics, proxies. So application area is for optimization problems where scare resource have to be allocated to maximize some objective function.
5:15:05
jeosol
A presentation may be able to help explain things better. Hence beach suggestion to come to ELS
5:16:43
jeosol
I was hoping to reproduce some examples using CLML library and make changes to the code if necessary. I am trying to resolve with the library owners to avoid any issues.
5:19:31
shachaf
Is there something in Lisp which is like progn, but where each statement can be a sort of macro that acts on the rest of the block?
5:21:03
shachaf
I'm thinking about a language feature for a different language. But I thought maybe Lisp people would've thought about something like this.
5:21:22
makomo
what does it mean "but where each statement ... acts on the rest of the block" though
5:22:05
makomo
maybe something along the lines of this, but i don't know if that's what you're looking for: https://fare.livejournal.com/189741.html
5:22:22
shachaf
I guess it would mean that (progn (a) (b) (c)) can turn into something like (a '(progn (b) (c))) if a is a particular type of macro.
5:23:55
shachaf
OK, that looks similar. Though I'm thinking that in the common case the things in the progn block are just evaluated as regular expressions.
5:25:15
makomo
i'm not sure if it's possible to do what you want, i.e. for A to act on the whole progn
5:25:42
makomo
you could for example invent your own PROGN-like thing that will be a macro that will codewalk the body and looks for A's :D
5:26:12
shachaf
Right, that's what I was thinking. I was wondering whether something like that existed.
5:26:51
shachaf
It's also similar to https://common-lisp.net/project/cl-monad-macros/monad-macros.htm (or Haskell's do notation)
5:28:02
shachaf
And I suppose also to continuation-passing style, or first-class continuations in languages that have them.
5:29:38
makomo
shachaf: you might want to look at the implementation of contiuations in On Lisp. i don't know how complete it is, but it could come in handy as an example
5:32:09
shachaf
But continuations are opaque functions and I'm curious about applications that do more syntactical macro-style things.
5:39:30
aeth
You could try looking at various utility libraries to see if any do something similar to what you're talking about
5:39:58
shachaf
(And also I'm thinking about this in the context of some sort of low-level language that doesn't have closures.)
5:53:28
fiddlerwoaroof
shachaf: you might look at f-exprs in the kernel language, among other places
6:35:52
MichaelRaskin
shachaf: I think this is sometimes implemented under names like nest or something like that
8:06:43
fiddlerwoaroof
You need to use the git version of slime, because emacs changed the signatures of some functions
8:33:20
xificurC
I'm reading LOL and gained a yet again little bit better understanding of lexical and dynamic bindings and closures. However I'm failing to understand one example the author gives: he says this doesn't create a new lexical closure: (let ((temp-special 'whatever)) (lambda () temp-special)). Note that temp-special was defvar'd before, i.e. made speci
8:34:19
xificurC
so if it doesn't create a lexical closure I would expect this to clobber the variable: (defvar *x* 1) (loop for i from 1 to 10000 do (sb-thread:make-thread (lambda () (let ((*x* 10)) (incf *x*)))))
8:34:32
jmercouris
I'm having a weird error says "COMPILE-FILE-ERROR while coming "cffi-toolchain" https://gist.github.com/284f9800691c84683301e12d68256b06
8:36:58
jmercouris
do not try to imagine what is happening in machine code, that will make you wrong a lot
8:37:24
xificurC
jmercouris: yes I read that and the sentence is ambiguous (to me at least). A special declaration in the let's scope or in toplevel?
8:39:27
jmercouris
and if you try to guess what it is doing, you are only going to confuse yourself and cause problems when you try to optimize "cleverly"
8:40:30
xificurC
jmercouris: ok forget the machine code then. In the example above, is the leted *x* dynamic or lexical?
8:42:46
White_Flame
the standard says that dynamic bindings are scoped to a function and everything it calls, which is necessarily thread-local on all implementations I've seen
8:43:46
beach
xificurC: It doesn't clobber the global value of the variable, because you bind it before incrementing it.
8:44:53
White_Flame
it's a compile-time decision on whether or not the variable is declared special, that determines what LET does
8:45:32
beach
xificurC: The tradition is also that each thread gets its own binding, and that they share the global value.
8:46:19
White_Flame
they can also be done via (defun foo (*x*) ...) which also establishes a dynamic binding for *x* using what's passed in
8:46:46
beach
xificurC: (defparameter *x* 0) (defun ff () (print *x*)) (defun gg () (let ((*x* 1)) (ff)))
8:49:03
White_Flame
a common machine code implementation is that when looking up the value of a special variable, first it checks the threadlocal table. If there's no binding there, it checks the global symbol-value of the symbol
8:50:21
White_Flame
and again, that choice is compile-time, depending on whether or not the referred variable is/was declared special or not
8:51:24
xificurC
ok, so in (defparameter *x* 0) (let ((*x* 100)) CODE-HERE) everyone using *x* at runtime will see the leted value, which is what dynamic binding is all about. The threading version works because specials can also be in a thread-local storage
8:52:48
xificurC
I still don't understand the sentence "the standard says that dynamic bindings are scoped to a function and everything it calls" though
8:53:14
White_Flame
(progn (let ((*x* 100)) ...*x* is seen as 100 here and in called functions...) ...*x* is back to normal)
8:55:41
White_Flame
(let ((*print-circle* nil)) (format t ...)) will cause FORMAT to see a new value of *print-circle*, for instance, but any other thread won't, nor will anything in the current thread outside the LET
8:56:08
White_Flame
specifically, outside the dynamic extend of LET, ie when it's active on the call stack and hasn't exited yet
8:57:34
xificurC
White_Flame: ah so I can imagine "if it's not on your call stack you can't see it"?
8:58:18
White_Flame
if a special binding has entered, then everything in the thread will see that new binding (unless another inner binding overrode it)
9:01:08
beach
xificurC: I know of no Common Lisp implementation that does it differently with respect to threads. Without threads, it is standardized behavior.
9:02:09
xificurC
beach: what other implications are there from this requirement? You're saying threads aren't mentioned but I don't see what else benefits from this behavior
9:02:47
beach
xificurC: As White_Flame pointed out, you can alter the behavior of things like FORMAT without passing an argument to them.
9:03:21
xificurC
beach: yes but if the binding wasn't thread-local it would still apply the same way
9:03:45
beach
xificurC: yes, but if the binding were a lexical binding, it would not behave that way.
9:03:59
White_Flame
" The effect of binding a dynamic variable is to create a new binding to which all references to that dynamic variable in any program refer for the duration of the evaluation of the form that creates the dynamic binding. "
9:04:51
xificurC
beach: yes that's the point of dynamic binding, I get that. I'm asking what other benefits are there from the fact that the binding is connected to the stack
9:05:46
xificurC
if it was altered in a global table that is shared across threads you would still have the same behavior with the FORMAT example
9:07:10
xificurC
White_Flame: so the standard doesn't mention threads but the requirements it imposes necessitate thread locality. And I don't see what other benefits are there from those requirements, i.e. why aren't threads mentioned
9:07:49
White_Flame
and threads aren't mentioned because they basically weren't invented at the time that the tech they were consolidating was created.
9:07:57
beach
xificurC: You are right. There are no other benefits to special variables than the fact that they allow dynamic bindings and that this is a unique property of Common Lisp.
9:08:37
beach
xificurC: A few minutes ago, you did not understand the mechanism of dynamic binding, so it is natural that we try to check that you now do.
9:09:19
White_Flame
the main benefit of special variables is side-band context, either global or scoped
9:09:25
xificurC
beach: I imagined it to work *not* thread safe, e.g. with a shared global table. But my test in sbcl proved me wrong
9:10:18
beach
xificurC: You also imagined something else, i.e. that (let ((*x* 1)) (incf x)) would alter the global value of *x*, which is not the case.
9:11:26
beach
So we are just making sure that you understand the benefits of special variables, even when there are no threads involved.
9:11:47
xificurC
I just imagined it to be something like (setf tmp *x*) (setf *x* 1) (incf *x*) (setf *x* tmp)
9:12:30
White_Flame
or (let ((old-x *x*)) (setf *x* 1) (incf *x*) (setf *x* old-x)) to be a little more idiomatic
9:12:44
shka
xificurC: essentially, each new binding to special variable shadows old binding for everything that comes after it on stack
9:12:58
beach
xificurC: Yes, and that won't work if there is an error and a non-local transfer between the save and restore.
9:13:21
beach
xificurC: Dynamic bindings are guaranteed to be undone in case of a non-local transfer of control out of the dynamic scope.
9:14:34
xificurC
I already understood and used the benefits of specials. I didn't understand why a let over it is thread safe.
9:14:56
xificurC
You guys said the standard requires it to behave in a way which is basically always implemented in a thread safe manner.
9:15:19
White_Flame
because "for the duration of the evaluation of the form that creates the dynamic binding" is interpreted that way
9:16:19
White_Flame
and scopes happen to be thread-local, by interpretation of that "during" description
9:19:17
xificurC
I was thinking "if I were to implement CL and read that line would the thread-safetiness be clear to me from that sentence?"
9:19:57
beach
xificurC: It's the only sane way of doing it. Otherwise, a thread could not count on the value of its own variables.
9:20:09
White_Flame
because the actual "time during which ... a binding ... is defined" is technically global, but unpredictable outside a thread
9:21:17
White_Flame
I think LOL is an interesting exercise, but I don't like the data-hiding of the way it uses closures
9:22:02
xificurC
beach: yes but you really have to think of threads to get a surprising effect from it when keeping it in a global table
9:22:53
White_Flame
a dynamic binding in a single threaded environment has well-defined boundaries. a global-trampling dynamic binding in a multithreaded environment loses those well-defined boundaries, while thread-local retains them
9:23:18
White_Flame
yes, but it also means you can't change them at runtime easily, which is very non-lispy
9:24:20
White_Flame
ie, if you create an object whose implementations are lambdas floating in hidden closure variables, then redefine the functions in the source code, the existing objects will nto be updated. If they were plain DEFUNs or DEFMETHODs, then the source code could change the behavior dynamically
9:24:30
beach
xificurC: In many respects, standard objects are strictly more general that closures, at least for SICP-style data hiding.
9:25:36
beach
xificurC: Since CLOS is so powerful, it is usually better to use standard objects than closures for data hiding.
9:26:41
jmercouris
beach: that sounds like a terrible idea, but I haven't done it, so I can't be sure
9:26:55
White_Flame
bad for debugging & development, in particular. You should still use well-defined interfaces and not just directly trample data, but explicitly barring ALL access is counterproductive in an interactive environment
9:28:24
White_Flame
having to pollute all your objects with logging functions, for instance, is a massive ugly nuisance, as opposed to letting your logger peek in as deeply as it needs to
9:28:59
jmercouris
even in OOP languages that have private members, they usually allow introspection and reflection
9:29:06
xificurC
but the world is a hostile place and the devs will try to kill your objects, you have to encapsulate!!! /s
9:32:46
xificurC
I always imagine the CL mascot from land of lisp just watching the programmers, year after year, implementing half-assed versions of what already exists for 50 years, scratching its head thinking just wtf is going on in other people's minds
9:34:00
makomo
White_Flame: i see your point about LoL. how would you for example "solve" the following problem: i had an object that you could (un)register callbacks with, and it would call these functions when a particular thing happened. the callbacks were taken as function objects.
9:34:46
makomo
White_Flame: now, when you pass in a function into this registration, such as #'SOMETHING, and later on redefine SOMETHING, you're still left with the old version of SOMETHING attached to your object
9:35:05
White_Flame
makomo: but I woudl probably define a struct or defvar to hold it (depending on scope) instead of just closuring it
9:35:52
makomo
White_Flame: since i wanted the benefit of interactivity/redefinition, i went with storing a symbol and then looking up it's symbol-function :D
9:35:54
White_Flame
makomo: right, because that's a _configured data object_, not just default class-style code
9:36:18
White_Flame
and yeah, symbols are the right way to do it if you want global redefinition of all instances to be possible
9:36:23
makomo
White_Flame: hm right, so it's not really a problem then, because you explictily did it that way
9:37:26
makomo
but i think LoL is a great book. it's an awesome lesson in macrology and a good brain strecher :-)
9:39:05
xificurC
makomo: I did a few years back but I didn't understand all of it. Reading it now (1/3 in maybe) and getting more from it
9:41:23
xificurC
I remember when I was reading it the first time someone here complained that defmacro! isn't safe when called in a nested fashion
9:42:34
makomo
xificurC: for example, sbcl processes the comma inside a backquote as a STRUCT i think
9:43:08
makomo
so codewalking the thing will give you a struct which is an atom (and also not a symbol)
9:44:56
makomo
the project aims towards a portable codewalker, but "portable" in the sense of using heuristics/specializing for different implementations, i think
9:59:26
jmercouris
I have no idea which system is defining this package, so I can't imagine how to fix it
10:02:13
jmercouris
when dropped into the restarts screen, is it possible to execute any arbitrary lisp in the image?
10:02:38
makomo
jmercouris: you can execute lisp code within any of the frames. press "e" in the slime window
10:07:41
TMA
jmercouris: but (find-package '#:static-vectors) returns #<PACKAGE "STATIC-VECTORS"> after (ql:quickload "static-vectors")
10:24:04
TMA
jmercouris: there is a problem with "static-vectors" on sbcl/freebsd then. I cannot help you further, I do not use freebsd. Sorry.
10:34:47
makomo
jmercouris: this seems to be the code https://github.com/cffi/cffi/blob/master/toolchain/bundle.lisp#L213
10:40:18
makomo
my idea was that the errors you got are because OS-COND wasn't defined as a macro or something
10:45:12
jackdaniel
downlaod prefered asdf (if you use sources, make will produce asdf.lisp file), and call (load (compile-file "asdf.lisp")) before quicklisp/setup.lisp is called
10:46:20
jackdaniel
QL first checks, if ASDF is already loaded (if so, it does nothing), after that it calls (require 'asdf) (that gives you asdf bundled with implementation). if this yields nothing (errors that module is not found), it loads asdf 2.26 which is bundled with quicklisp as a fallback
10:47:15
shka
is it sufficient to wrap defclass in optimize for safety 3 in order to ensure that i won't get the wrong type?
10:49:54
White_Flame
I would think it is highly dependent on when/where CLOS dispatch is recompiled, and if slot accessors are inlined somehow
10:52:11
jackdaniel
if you really want to load custom ASDF - I think yes. but maybe I have confused things (as Xach's veto would suggest)
10:52:37
jackdaniel
shka: I think he was referring to my sloppy explanation of ql algorithm of ensuring ASDF
10:53:43
jmercouris
jackdaniel: I was under the impression that sbcl --load quicklisp.lisp will already handle this?
10:54:23
jackdaniel
because QL calls require for asdf module, which is bunded with the implementation (if no asdf is loaded beforehand)
10:56:13
jackdaniel
I have a trust issues with ASDF upgrade mechanism, but in principle you should be able to load ASDF on top of existing ASDF
10:56:29
jackdaniel
because Quicklisp does call require ASDF for you (as I have pointed out *twice* already)
11:54:41
shka
jmercouris: when i started programming in C++ i had this very old machine with athlon 3200+ and 2GB of RAM
13:06:43
shrdlu68
https://imgur.com/a/hy7tRe4, screenshot from https://youtu.be/Z4oYSByyRak?t=11m40s
13:07:38
shrdlu68
His assertion is that it is not possible to handle heap exhaustion in Lisp, among other languages he mentions, and thus "it is impossible to write perfect software in these languages">
13:08:07
jmercouris
what does it mean to write "perfect software"? of course it is possible to prove lisp programs
13:09:07
jackdaniel
perfect software is the software which meets criteria subjectively chosen by the person who presents the topic ;)
13:09:34
jackdaniel
shrdlu68: in principle yes, implementation may raise a condition (and they often do)
13:13:05
jmercouris
better usage of your time might be reading about how to prove programs, and the set of languages that exist for proving programs/algorithms
13:13:17
jmercouris
of course, they have not lived up to the hype, but they are still interesting ideas
13:13:32
shrdlu68
His argument is, that function will always return the correct output for the correct input - there won't be malloc errors, etc.
13:14:06
jmercouris
just because a program has state or memory does not mean that it cannot be proven
13:15:18
jackdaniel
that reminds me a discussion whenever CL allows arbitrary big integers or the physical computer limitation counts here and CL can't have arbitrary big integers
13:16:29
shrdlu68
If one attempted to add two large bignums on a system that's running out of memory, what exception would a lisp implementation raise?
13:16:52
_death
it's like saying 1+1=2 is false because some gamma ray flipped a bit.. different levels of reality
13:18:15
jackdaniel
which is a condition inheriting from storage-condition, which inherits from serious-condition
13:20:56
jackdaniel
jmercouris: you may say whatever you want – that doesn't mean people will understand you
13:22:48
jmercouris
jackdaniel: I am asking, IF we can agree that this condition is not defined in the CLHS and it results in undefined behavior, based on that youtuber's definition, can we say that CL is "non-perfect"?
13:28:26
jmercouris
jackdaniel: yeah, the perfection crtieria is that one guy's perfection criteria, not myo wn
13:29:15
jmercouris
I think my sentence is pretty clear, though I also understand the point your making, "what is perfection"
13:29:53
shka
is it correct? http://www.crategus.com/books/closer-mop/pages/sb-mop_fun_slot-definition-type.html
13:29:54
jackdaniel
if it is: doesn't have threads in the specification, CL is not perfect. if it is: doesn't have defined behavior for memory exhaustion in the spec, CL is not perfect. ;) fwiw he was talking about a perfect software, not a perfect language (judging from the screenshot)
13:31:19
jackdaniel
copy-paste from http://metamodular.com/CLOS-MOP/slot-definition-allocation.html ?
13:34:00
p_l
until it's pulled from under you externally, like typical case for C program on Linux, or the essentially equivalent case of people disabling GC on early LispMs
13:34:55
jackdaniel
p_l: I don't know about other implementations, but ECL has preallocated memory for reporting memory conditions
13:35:46
p_l
jackdaniel: well, it's *ECL*, not "le random C/C++ crap written on and tested on only on Linux" ;)
14:37:32
vindarel
Hello (common) lispers, little question on capturing standard output. I know with-output-to-string, but this doesn't suit my need because I'd like to return the string immediately, to not break the printing of the application. I'd like something like a defadvice, but this doesn't exist in SBCL. Do you think of something ? thx
14:38:40
Bike
do you mean that you want to print to standard output but also capture it in a string?
14:40:04
vindarel
Actually I don't care to capture to a string, I'd like to change it before it is printed (to highlight stuff).
14:42:50
vindarel
A reader macro ? I'd like to change output from third party code, that won't use the reader macro.