freenode/lisp - IRC Chatlog
Search
3:18:59
White_Flame
I don't understand why compile is considered more valid than eval for runtime-generated sexprs
3:20:23
jcowan
https://codegolf.stackexchange.com/questions/53250/optimizing-ski-compiler is a compiler for SKI machine specifications; the CL version uses progv.
3:21:16
White_Flame
obviously, the article is using COMPILE's sexpr->executable facility as its primary feature, which is generally equivalent to EVAL in "wrongness"
3:25:05
LdBeth
<freenode_jco "claiming that `compile` evades t"> jcowan: you can use closure to avoid compile at run time
3:33:38
LdBeth
White_Flame: that’s like... you want to compile a file and of course one cannot avoid doing actual compilation
3:35:11
White_Flame
yeah, if you just mean CPS with your closure above, that's something I've done before
3:37:57
White_Flame
I mean trace through an AST for an expression, linking up pre-compiled lambdas together with CPS to yield a basic executable form of it
3:41:31
White_Flame
right, the above linked "eval is bad" to the same thing that compile does, in turning data into executables
3:41:56
White_Flame
then an idea of only using closures was presented, but doesn't do the same thing
3:44:41
LdBeth
Well it’s just happened to be calling a lisp compiler to compile sexps but the principle is the same as calling a C program translate SQL strings to a more compact form
3:47:18
White_Flame
depends on if the specific principle distinguishes between software interpreters and compilers :)
3:48:01
copec
It would be cool to have a distribution of typical results per language...like get the students to all implement one of the problems at the end of an algorithms course or something
4:05:23
elderK
I'm writing my own binary-structure kinda thing. Mostly for fun, but also because I found some deficiencies in other ones.
4:05:39
elderK
Anyway, you have some "binary type", which is like a primitive type that can be extracted or read.
4:06:34
elderK
Anywho, The "primitive type" could be anything, say, u128/be or whatever. I want to have a generic function that computes the "lisp type" of that primitive. So, if I had say, u32, I'd get (unsigned-byte 32)
4:07:45
elderK
It's not a header, though. It's just some primitive type that can be extracted. LIke an integer or float say.
4:12:12
LdBeth
Ah, you say it can be a string, so I thought it can have some other structure as type
4:12:45
elderK
You can define "binary structures" that will be parsed from disk, say. Like in PCL. Structures have slots that are other "binary structures" or say, "primitive types." These primitive types are things you define - like u32, u16, whatever. PCL does not generate any type information for the "slots." I will. So, given some "primitive type" (not a Lisp type), I need to generate a "Lisp Type."
4:13:51
elderK
What the mapping is, and how to read / write "primitive types" is set by a macro, define-binary-type, to use PCL's name.
4:15:20
elderK
Another question, is like, what's the deal with error reporting / validation from within macros? say, I want to ensure that someone uses the macros correctly.
4:19:55
pillton
The term, macro, is short for macro function. You can signal errors in macro functions if you like. It is probably best to do so.
4:21:55
LdBeth
About the other question, unfortunately you have to handwrite checking and error reporting, however it might be time to adopt @beach ‘s concrete-syntax-tree lib which has parser utilities for common macro constructions
4:55:52
aeth
Also destructuring-bind. That will catch a bunch of syntax errors that you can't express directly in the macro's lambda-list
4:56:29
aeth
something like this: (dolist (sublist list) (destructuring-bind (foo bar &key baz quux) sublist ...))
6:46:09
elderK
Hmm. I'm trying to unquote several levels. It's weird. Saying something like ,,something results in an expansion of ,whatever
6:59:52
fiddlerwoaroof
One trick that often helps is have your first level of quasiquotation call functions that do the actual parsing/construction of forms.
7:01:07
fiddlerwoaroof
e.g. here I've split the generation of the resulting expression across several functions and let bindings: https://github.com/fiddlerwoaroof/fwoar.lisputils/blob/master/fwoar.lisputils.lisp#L131
7:12:05
elderK
I don't think the way I'm trying this is really working out. I defined a generic function to like, handle the validation and expansion of certain "forms" in my ... macro
7:12:44
elderK
A method, expand-specifier would be executed, keyed on the :reader. It'd check the form was sane, then generate the appropriate expansion
7:38:54
fiddlerwoaroof
It works really well, but I've always been a bit concerned about the implications of this bit of the standard: "defmethod is not required to perform any compile-time side effects. In particular, the methods are not installed for invocation during compilation."
7:39:42
fiddlerwoaroof
I believe this essentially means that your defmethods need to be in a different compilation unit from the use sites of the generic function, if you want your code to be portable
8:01:37
no-defun-allowed
why does SBCL have `&rest args` in the lambda list for POSITION? it's not there in the clhs.
8:07:14
no-defun-allowed
my guess is it eats keywords it doesn't accept, it's present in some other functions too
8:12:43
jackdaniel
having '&rest args &key …' is useful, when you want to pass args further without extra consing
8:15:36
no-defun-allowed
now i realised using lambdas as arguments to a CLOS thing was a Bad Idea and multiple dispatch would have worked better
8:15:49
no-defun-allowed
or something like that. either way i'm wading through funcalls to fix it now :')
8:16:36
jackdaniel
you may want to look into filtered-functions (library written by Pascal Costanza)
9:03:36
elderK
:( Man I know what I want to do, and what I want to generate. But I'm having a really hard time doing it in a way that I feel comfortable with
9:04:32
elderK
Out of curiosity, if a macro is exported from a package, and uses some functions that are defined in that package but not exported, will it still expand correctly if you import that macro into another package?
9:04:46
elderK
Like, the macro is imported. But the things the macro relies on, are "internal" to the package we're importing from.
9:05:15
elderK
I get the feeling it is. I'm pretty sure I read somewhere that the stuff that's in effect at the time the macro was defined, is what is used when it is expanded.
9:07:49
elderK
Is it okay to expand to a (progn) in a macro expansion, if say, something is optional and you don't want to include it?
9:08:40
elderK
Like say, the macro proper makes a bunch of calls to helper functions, to actually generate expansions. But maybe one such helper detects that an optional element of the macro isn't present. Ah, thanks jackdaniel.
9:12:59
no-defun-allowed
my reading of the clhs says "no using it outside the dynamic extent" which i think is outside that part of the stack, so "no" but idk
9:13:22
fiddlerwoaroof
For a lot of places where you would walk the body like a tree, you can just use macrolet to define a local macro that handles the car of the subform you're interested in
9:14:52
shka_
what you can even do is to generate both flet form and symbol-macrolet that will expand into call
9:18:16
fiddlerwoaroof
because the forms you don't generate a symbol-macrolet for don't turn into function variables
9:20:23
shka_
trick is that symbol-macrolet maps to labels, labels ensure that let is initialized and let form store actual value
9:20:27
elderK
fiddlerwoaroof: I'm not sure I really understand at this point. But it sounds very useful.
9:20:58
elderK
Gosh, I wonder how long it will take until I feel comfortable :( I guess I'll finish what I'm working on now, it'll probably be pretty horrible. But at least then, I can get feedback and iterate on it
9:58:17
dim
elderK: well I would say that the point about macrolet usage in macros is pretty advanced stuff, maybe the call-with- trick is a better way to get starting with macros
9:58:40
oni-on-ion
i am wondering to myself why lisp-1 would be annoying where lisp-2 is nice, because who names functions and variables the same without introducing obfuscation? and is that actually a more frequent requirement than working with functions without special [fun]calls?
9:58:52
elderK
dim: I'm not sure if what I'm trying to make is considered "more than what a newcomer could do" or not D:
9:59:06
elderK
Life would be made a lot easier if I used alexandria, but I would like to stick to the core language for now.
9:59:31
dim
well if you're having to use macros, it qualifies at more than what a newcomer is expected to play with I would gather
9:59:53
fiddlerwoaroof
oni-on-ion: honestly, something like (swap (list) (list* (cadr list) (car list) (cddr list))) reads just fine
10:00:22
fiddlerwoaroof
For it mirrors noun/verb ambiguity which generally isn't a cause of misunderstanding
10:01:34
fiddlerwoaroof
The compiler can check the symbol's function cell to see if a function has been defined
10:01:37
oni-on-ion
i asked schemers "why is t #t and not t?" and they say "because you might want to call a variable t" . cringe
10:02:12
aeth
oni-on-ion: Implement <insert formula from physics here> and you probably want to use the variable name t
10:02:24
fiddlerwoaroof
Also, there's plenty of ways to avoid funcall: FLET/LABELS or write a bunch of combinators that take functions and return lambdas
10:02:30
aeth
oni-on-ion: And even worse, if it's from mathematics closely related to physics, it is just t, it isn't time
10:03:02
oni-on-ion
aeth: thats a real reason? i use t all the time. but there are other letters. it feels like you could be suggesting "why not have a (varcall x)" then !
10:03:16
fiddlerwoaroof
e.g. (funcall (over (juxt #'car #'cadr)) '((1 2 3) (2 3 4))) ;; => '((1 2) (2 3))
10:03:23
oni-on-ion
or; why are functions especially-accessed instead of variables ? what if it were the other way around?
10:04:35
aeth
oni-on-ion: It's more like if a language used both "pi" and the actual greek letter "π" to mean something unrelated to the constant. I mean, sure, you could call 3.1415... something else, but the clearest name is probably pi.
10:05:10
aeth
alexandria:lerp uses v but literally all material everywhere else will use t here: https://gitlab.common-lisp.net/alexandria/alexandria/blob/e5c54bc30b0887c237bde2827036d17315f88737/numbers.lisp#L89-100
10:05:50
fiddlerwoaroof
Anyways, I can say that everytime I write javacript or clojure, I miss lisp-2s
10:06:31
aeth
oni-on-ion: t is basically the one place where Scheme has an advantage over CL against name collisions (usually Scheme's the language with the problem there)
10:07:20
fiddlerwoaroof
Also, a lisp-1 needs a hygenic macrosystem more than a lisp-2, especially if it doesn't also have something like packages
10:19:47
LdBeth
Then you should notice PLT’s macro operates on the “syntax” which automatically provides error checking
11:45:24
minion
progv: PROGV is a testament to the success of synthetic methamphetamines in the rearing and education of the inveterately brain-damaged contributors to the X3J13 standardisation proceedings
12:01:02
ogamita
Yes, harsh. At least for the California side of the comitee. They learned to use LSD creatively there. To wit, Steve Jobs, etc.
12:31:33
larsb
Just wanted to say we do have Muddle running on ITS on a PDP-10 emulator. Come over to #PDP-10 if you want to know more.
12:44:38
jcowan
A more principled Scheme answer would be "Scheme doesn't restrict which identifiers can be lexically bound."
12:59:58
jebes
how does ecl and abcl stack up against sbcl/ccl? I've heard ecl talked about favourably here.
13:01:10
jackdaniel
but ecl may be used to deploy your library as a shared library (and use it from i.e C application as i.e my-library.so)
13:01:20
jebes
jackdaniel: so if i was writing a high performance game/code base, the benefit of ecl's c integration might be outweighed by its speed?
13:03:19
jackdaniel
datapoints: ecl is slow with gf dispatch, we plan to work on it after the upcoming release
13:03:40
jcowan
Does anyone know how to find the "all issues" page in the clhs, or even if there is such a page? Dr. Google not helpful.
13:04:42
jackdaniel
ecl can't save the image (so you don't have save-lisp-and-die, you compile software from files)
13:05:13
jackdaniel
I don't know how fast / slow is ghc or c++ with gcc. compilation time penalty comes from invoking gcc
13:06:22
jackdaniel
you may be interested in talking with dto and borodust on #lispgames (there are others who work with games and lisp, but I know that both worked with multiple cl implementations)
13:12:54
jebes
how hard is it to reduce consing in lisp? Is it possible to get it to 0 or close to zero?
13:17:11
borodust
hi jebes, yes, it is possible to make tight game loops non-consing, aeth is one of the masters of such art
13:17:14
jackdaniel
(one more datapoint: statically-linked application built with ecl when stripped may fit in ~5MB)
13:20:35
borodust
last time i tried ecl was much slower than sbcl/ccl for my grossly unoptimized games, but aeth had very important suggestion i didn't try out yet that might improve ecl performance - for some reason by default cffi defines very slow method of calling foreign code for ecl
13:21:27
jackdaniel
it is indeed around 80x faster, but to make it default I need to work a little on passing original pointer declarations
13:22:41
jackdaniel
(right now cffi, when you declare something to return (char *), passes (void *) downstream to the implementation, what doesn't really work when you compile with C compiler)
13:23:26
jackdaniel
but lately (a few months ago I think) I've managed to make vaarg calls work OK, so it should be already faster with default being :dlopen now)
13:24:33
jackdaniel
nope, dlopen is not default yet, probably because of pointers still not being carried correctly
13:26:14
jackdaniel
but it is not guaranteed to work if you have functions in there which return pointers to something else than void
13:27:38
borodust
well, that's unfortunate, but we will see :) i think it's all :pointer down the road, which i guess is translated to void* anyway
13:29:05
ogamita
jebes: for one thing, it is not specified how much consing an implementation may do. So you can find that a set of functions in CL don't cons on one implementation, but cons on another.
13:29:55
ogamita
jebes: Then, the main problem is that consing and garbage collecting are not costly operations. It's like fork in unix: they're over optimized by lisp implementations.
13:30:14
borodust
ogamita: when building games (or end product in general), we don't care about portability often, because we have a privilige to choose an implementation we want to build end-user executable with :)
13:30:34
ogamita
jebes: So minimising consing means minimising one of the fastest operations of a lisp system, and replacing them by slower operations!
13:32:20
ogamita
jebes: you may have a look at http://cliki.net/Performance, there are some links about making Lisp faster than C.
13:32:35
borodust
jebes: you can write assembly in lisp! ;p see sb-cga which i already mentioned, but please don't :D prematur... well, you know
13:33:18
jmercouris
is creating a bunch of defgenerics an implication to the users who extend a class that they should probably implement those methods if no default implementation exists?
13:33:19
ogamita
jebes: one good trick, is to use pre-allocated objects (eg vectors), and upgraded arrays for things like double-float that would require boxing (a kind of consing).
13:34:18
ogamita
Take a lisp expression, and write a specific compiler generating optimized assembly, knowing your context.
13:36:32
borodust
jebes: e.g. assembly-in-lisp (sbcl-specific) https://github.com/nikodemus/sb-cga/blob/master/ports/sbcl.lisp#L137-L145
13:39:34
ogamita
Yes, the problem with sbcl, is that so many programmers using sbcl don't care about conforming or portability. Of course quicklisp only tests compiling with sbcl. So if you use sbcl, even if you try, you're bound to use sbcl specific libraries and APIs…
13:40:03
jebes
when i write normal non insanity driven lisp, i like to test on multiple implemtatios
13:41:05
borodust
ogamita: well, sb-cga has code for other implementations which makes it portable, it's just helluva lot slower on other ones
13:41:05
jmercouris
using sbcl specific extensions and making your code non portable should be IMO a crime, unless absolutely necessary
13:41:25
makomo
jmercouris: i'm thinking the same thing hah. "restricting" yourself to portable CL sometimes feels like you're missing out :D
13:42:47
jmercouris
because people will basically RELY on SBCL existing and being ported to their platform
13:44:09
jackdaniel
1. official ql policy is that library works at least on two implementations; 2. portability libraries are commonly used (bt for instance)
13:46:47
jackdaniel
" < jmercouris> the only solution is to pull in as few dependencies as possible" sounds super-dramatic to me
13:47:50
ogamita
jackdaniel: well, one problem is that there's no declaration of the supported targets for portability libraries and for cffi libraries.
13:48:30
ogamita
if asdf had such declarations, you could compute the intersection of the supporter targets for all your dependencies. (and find often, that you only have one or two implementations in there…)
13:48:46
shrdlu68
I like to take a look a look at the pgloader issues page because it reminds me of the actual issues I'd run into if I chose to write some tool in CL.
13:50:31
ogamita
Nowadays, you have to choose between C89, C99, C11, C18. Between gcc, clang, icc, msvc, etc; Various version of gcc with different features (and pressed by clang, it obviously adds new useful features all the time now).
13:51:47
jmercouris
though YMMV depending on how you've set-up your data and whether you are using mysql etc etc
13:54:33
jmercouris
All code does really well with ORMs has nothing to do with whether it is functional, it serves as a nice abstraction
13:54:51
jmercouris
I don't want to imagine what the underlying tables look like, I don't care, I am only working with objects
14:03:06
ogamita
Basically, SQL is for RELATIONAL databases. RELATIONAL databases are a good mathematical way to represent data and query it easily. But it is not the way real data in the real world is structured. In the real world, your healthcare file is not stored in tables with the healfcare file of all the other patients. In the real world, it's in a folder and you bring it with you, as an instance of person, to the next instance of doctor, to
14:03:37
ogamita
So basically, what ORM show, is that you should throw away SQL and RDBMS, and get yourself an OODBMS.
14:04:08
ogamita
The other problem that this denotes too, is how (the code of) applications are distributed amongst systems.
14:04:22
pfdietz
It's data as viewed by a large organization, not by a customer. As a customer, you don't care that your data fits (perhaps poorly) into tables with other customers.
14:05:02
ogamita
With a RDBMS, you'd have most of the logic of your application in stored procedures. With OODBMS, it's in methods of objects. But you need a OODBMS that can store objects with their methods in the database, and run those methods on any processing CPU that access it!
14:06:28
ogamita
As you can see, quite a mess. By the way, java (and applets) could be used that way. But there are no such system in use. The web ate java and applets, digested it, and threw it away, replacing it with ecmascript. (so called "javascript").
14:07:24
ogamita
But my point is that even OODBMS have difficulties because of this running of methods in the processing CPU.
14:07:59
ogamita
Or not. After all, with mobile applications, you often have this model where only the UI is on the mobile, the processing is done on the backend thru the web API.
14:09:10
ogamita
Now, perhaps you could do something usable, by hooking Common Lisp as stored procedure language in Postgresql.
14:09:37
ogamita
p_l: it's to run lisp program eg. in ecl on Android, and interact with java over a socket to do the UI in Android.
14:11:27
p_l
why not use JNI and possibly ring buffers (especially if shared data structure could be done)?
14:13:54
ogamita
well, you'd have to use libecl in that case. I feel safer with a separate process and sockets.
14:18:36
p_l
but it gets you idiots who read a header "R3 Corda used in finance..." and immediately look for "FEDCOIN" to invest into ;)
14:19:20
jebes
i do not feel comfortable being grouped in with people that use blockchain unironically
14:29:09
elderK
Well, after a few hours, here is my first "shot" at a set of macros: https://pastebin.com/wHu3kSu3
14:32:56
elderK
Yes, it does but it destructures. So, doesn't that ensure each "binding" has the correct form?
14:35:28
jackdaniel
(let ((a (foo-with-side-effects)) (b (bar-with-side-effects))) (if (and a b) … …))
14:39:37
elderK
I wonder how you'd do that. You could recursively expand it, or I guess you could have something like (and (setf ... ...) ...)
14:40:09
jackdaniel
there are two ways, either nested let (recursive expansion) or a block/return-from combo
14:41:58
pfdietz
But you can find out, using MACROEXPAND. Each implementation may do it differently.
14:42:58
jackdaniel
(let ((a (or ,form (return-from bam nil)) (b (or ,form2 (return-from bam nil))) …)
14:46:14
jackdaniel
ah, alexandria reserves when-let* for doing it one-by-one (there is no if-let* though)
14:48:54
makomo
jackdaniel: hm interesting. what would the semantics of IF-LET* be though? if one of the variables is NIL, what exactly can you expect to be bound within the ELSE?
14:50:09
makomo
i suppose WHEN-LET* is acceptable because there's really no ELSE. it's just "ok, never mind then"