freenode/#lisp - IRC Chatlog
Search
3:49:18
russellw
FAQ: 'If using REMOVE and DELETE to filter a sequence, don't use the :test-not keyword or the REMOVE-IF-NOT or DELETE-IF-NOT functions. Use COMPLEMENT to complement the predicate and the REMOVE-IF or DELETE-IF functions instead.' - a curious recommendation. Is there a reason for it?
3:55:30
aeth
As far as scary loops go, how does this one rank? https://gitlab.com/zombie-raptor/zombie-raptor/blob/d5023f05b40a20d3e0cfe96d0a6c4a85e39c4792/util/array.lisp#L115-149
4:00:28
|3b|
ACTION also wonders why it should be correctable if ROW-OF isn't an integer, but if it is any integer other than 2,3,4 that is fatal
4:01:05
aeth
|3b|: It isn't actually correctable because check-type in macros isn't actually correctable, at least in SBCL where I do my testing.
4:04:19
aeth
even if I violate ALGOL style and put the DO at the start of the line, that still won't happen
4:05:37
aeth
What I don't like about the loop I wrote is that I parse slot twice to get the slot-name twice, once in the loop body and once in the destructuring-bind that parses the whole thing if it's a list
4:05:51
mfiano
If you use keyword symbol loop keywords (loop uses symbol-name anyway), with the proper SLIME variable set, your clauses will line up (it might even be the default - it's been a long time since I used SLIME).
4:06:19
|3b|
you could do part of the destructuring in the LOOP and only parse the keys in the inner part
4:07:44
|3b|
for .slot in slots for slot = (if (atom slot) (list slot slot) slot) ... or whatever makes the rest work without testing
4:09:45
mfiano
It seems Sly behaves sanely even without keyword symbol loop keywords https://files.lispcoder.net/images/screenshots/img-20180901000917.png I really don't miss SLIME if it does that.
4:13:56
aeth
|3b|: Your solution is clever but it doesn't actually simplify much because I still collect something differently if it's a list so I still need to do the test the second time
4:16:52
|3b|
(if they can't be meaningfully duplicated, why bother with the hash to avoid making extra gensyms, if they can be, does it actually work as intended?)
4:17:36
aeth
|3b|: The macro looks like this in actual use: https://gitlab.com/zombie-raptor/zombie-raptor/blob/d5023f05b40a20d3e0cfe96d0a6c4a85e39c4792/render/gl.lisp#L195-206
4:17:39
mfiano
Also wonder why you spend this much time refactoring macros into a completely different form from using mapcar.
4:18:06
mfiano
I actually had that file open in my browser for a couple days, and I was looking at the tabs side by side and something didn't add up
4:18:13
aeth
The only thing that I changed in my refactoring is adding :elt so that I could use destructuring-bind
4:20:34
aeth
|3b|: The idea is that when accessing 2D arrays, the row is constant, but the column in the row can change, as can the array.
4:21:58
aeth
It can also be a 1D array (if neither :elt nor :row-of is given) so there can e.g. be a bit array whose index corresponds to another array row number.
4:22:28
aeth
The row (or index if it's 1D) is called "ID" because in my engine it almost always represents an ID
4:23:03
aeth
This is what happens when you have a large program gradually refactored over many years
4:23:56
mfiano
It doesn't help that you have changed game ideas 3-4 times since I heard you talking about your engine
4:24:26
aeth
mfiano: To make them smaller in scope each time. The only substantial change was going from first person to third person motion so I wouldn't need anywhere near as much physics completed
4:27:56
aeth
mfiano: do you think it would look better if I have (loop\n so that all of the keywords line up?
4:30:43
aeth
Okay, so I just switched them to keywords and put the :do at the start of the line https://gitlab.com/zombie-raptor/zombie-raptor/blob/839c898ba33e35003244e630edb58b01d5fce3b6/util/array.lisp#L115-149
4:32:07
mfiano
I really sort of feel sorry for ewhoever has to read that. It's pretty hard to scan and get an idea at a glance...I have to try to understand it :/
4:33:45
aeth
mfiano: One of the reasons it's going to be a *long* time before I encourage anyone to use this is because of some of these macros
4:34:44
mfiano
Copying that into my Emacs: https://files.lispcoder.net/images/screenshots/img-20180901003426.png
4:35:42
aeth
mfiano: well something broke in my .emacs then because the reason I used symbol loops instead of keyword loops is because symbol loops indented properly and now they're both... broken
4:46:08
_sfiguser
guys which compiler do you suggest for lisp i see that the most common ones are "abcl" "ccl" "clisp" "ecl" "sbcl"
4:46:09
ealfonso
I wonder if anyone is active right now... Is there a built-in function to extract a common prefix from a set of pathnames or strings?
4:47:42
aeth
_sfiguser: The most are afaik actually SBCL and CCL in that order. CCL has better support for threading on macOS and has a faster compiler. ECL should be your next choice if neither works. It's designed to be embedded into C programs as a scripting language, hence the "E" in its name. ABCL is niche (the niche is the JVM).
4:48:17
aeth
_sfiguser: CLISP is maintained, but they haven't had a new release in a long time. i.e. its git (or SVN?) is still being updated, but the activity isn't enough for a new actual released version at the moment
4:49:34
aeth
I would personally avoid CLISP and ABCL unless you need what they offer because they have quirks that make them different. (I've run a lot of the same code in almost every Common Lisp, using Roswell.) Yeah, they conform to the standard, but lots of *your* assumptions might not.
4:52:20
aeth
(In case I was unclear, CCL compiles faster. SBCL's compiler produces faster code, in general.)
4:57:44
beach
_sfiguser: You asked before why Lisp is not popular, despite being so good. That question assumes something that is just not true in the real world, namely that people are rational and that they choose the best things for what they need to do.
5:05:36
beach
_sfiguser: Common Lisp is a language with a standard, published by an independent standards orginaization.
5:06:20
beach
_sfiguser: Racket is an implementation that has no independent specification. It can change over night and break all your software. Or it can be abandoned because the current maintainers get tired of it.
5:07:03
beach
_sfiguser: When I give talks to industry, I say that a project leader that chooses a language without an independent published standard should be fired.
5:07:24
beach
Because that project leader puts the product and sometimes the entire company in a very difficult situation.
5:09:24
buffergn0me
Have a client with a system on 2.7 right now, the "upgrade" path is to rewrite in node.js...
5:10:14
buffergn0me
In contrast two weeks ago I migrated another client's Common Lisp system to a new server two weeks ago. Has not been touched in almost a decade and still runs fine.
5:12:30
aeth
_sfiguser: You just got a new reason. Stuff from 1994 will run fine today without any modifications, and stuff before Common Lisp from the 1970s will run with very minimal modifications, if any.
5:15:36
beach
https://pdfs.semanticscholar.org/presentation/fb4b/bf38068e9044acc007c723e8a13cfb14ba48.pdf
5:15:50
aeth
_sfiguser: It's usually in the 3x to 5x slower range, e.g. (as SBCL) https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fast.html
5:16:10
beach
_sfiguser: Besides, as I often say in my talks, it is impossible to write a C++ program that is both fast and maintainable.
5:17:20
jackdaniel
imho in moderate size applications and bigger most bottlenecks come from bad architecture / data structures / algorithms
5:17:56
buffergn0me
There are just no CL implementations that do tracing or profile-guided optimizations
5:18:05
aeth
_sfiguser: For the most part, if it's slower it's because not as much attention is put into compilers compared to something like GCC or LLVM, which will do some amazing optimizations. (Except those optimiziations don't make the language *that* much faster!)
5:19:37
beach
So heisig just told me that there is a paper that allocating an instance in CLOS is faster than allocating an instance in C++, for the simple reason that malloc()/free() is slower than most GC systems used by Common Lisp.
5:19:37
aeth
jackdaniel: Where Lisp really shines is where you need to do something messy but can hide it in a macro so it still is readable
5:20:35
jackdaniel
aeth: where lisp looks really ugly is where you need to cut some bullshit abstraction hidden behind macros
5:20:57
buffergn0me
jackdaniel: Does lightning do tracing? I thought it was just an assembler-as-a-library
5:21:04
aeth
jackdaniel: as long as it's not a code-walker it's not normally bad. Code walkers are evil, though.
5:21:38
jackdaniel
buffergn0me: I'd expect JIT on clisp part *using* gnu lightning; but I'd have to read into clisp to confirm that
5:27:21
aeth
buffergn0me: Do CL implementations have enough to JIT Foo when you have a Foo->CL compiler? e.g. JS->CL. JS basically relies on JIT.
5:30:22
buffergn0me
jackdaniel: Yeah I heard about that. CLISP is using lightning to native code compile their bytecode. So in that sense every CL implementation with a compiler can be a JIT, and Lisp is the "original" JITed language. The problem is today people have started using the phrase JIT to refer to tracing- and/or profile-based runtime optimization. Which is a very different technique.
5:31:34
buffergn0me
aeth: Yeah, CL-JavaScript is definitely a JIT JS implementation. And it was faster than Seamonkey when it first came out.
5:36:11
drmeister
Is anyone good with writing setf forms? I've got one that's not quite what I need and I'm a bit stuck with it.
5:36:53
aeth
buffergn0me: Probably not. I'm reminded of https://accidentallyquadratic.tumblr.com/post/142387131042/nodejs-left-pad
5:37:51
drmeister
If the value doesn't appear in alist - then I need (cons "key" value) to be pushed into the alist.
5:39:13
drmeister
I'm kind of stuck with strings as keys because I'm translating a bunch of stupid Python to Common Lisp.
5:44:08
jackdaniel
then take define-alist-get assoc from alexandria and tweak its define-setf-expander expansion to suit your needs
5:54:25
drmeister
buffergn0me: No - I'm kind of stuck with alists - it's the closest thing to Python's dictionaries that work with **keys.
5:57:22
dim
I guess I don't understand what makes the **keys calling convention in Python something interesting for your CL design here
5:58:37
drmeister
Well, (1) we started with alists and now we are kind of stuck with them (2) we have a LOT of very small dictionaries - so alists aren't such a bad idea.
6:00:04
dim
each time I'm using alist or plist directly I wish I had done some abstraction layer to use a gethash like API on top of them
6:00:05
drmeister
buffergn0me: Yeah - you are right about plists and **keys. There are a couple of other things I haven't mentioned. Namely someone else chose the alists and so we are kind of stuck with them.
6:00:48
jackdaniel
buffergn0me: arguably alists are better organized, each entry has both key and value and there is no mistake about which entry is what (separate lists)
6:01:41
dim
drmeister: how much work would you anticipate moving from alist to your own abstraction would be here?
6:01:49
phoe
Except if you go (setf ([] alist "d") 3) you want this to become a no-op, because the value 3 is already present in ("c" . 3)
6:02:37
buffergn0me
Haha, that is a fair point. I was just reading an article by Wirth about how no one ever uses abstract data types...
6:02:58
dim
drmeister: nobody ever has the time, when you look at it that way, the other angle being how much time are you going to spend because you did NOT move from alist to your own abstraction? how much deeper do you want to dig this hole?
6:02:59
drmeister
See, we translated jupyter widgets to Common Lisp. Then we translated nglview (a molecular viewer) and now we are translating bqplot (Bloomberg plotting library).
6:04:57
phoe
this means to me, "do all of the mutation unless the key is already present in the alist somewhere"
6:05:01
dim
drmeister: my remark is more to the level of “hiding it in a macro”, I think you might consider making it obvious in a data structure / api
6:05:25
jackdaniel
phoe: what's the point of such juggling if he can simply hardcode test in setf expanded copied from alexandria?
6:05:50
drmeister
dim: It made the code very hard to read with all the (cdr (assoc key table :test 'string=))
6:05:53
phoe
jackdaniel: that's what I mean - he can insert that test into the setf-expander from alexandris
6:06:09
buffergn0me
The last number I encountered from someone that benchmarked was 100 entries for list vs hash table break-even
6:06:31
jackdaniel
I've seen a lot of "if, unless, conditionally", sounds much more compliacted. but maybe I'm not following careful enough
6:06:50
buffergn0me
That was about a decade ago, it's probably even worse for hash tables today because of larger cache sizes
6:11:57
dim
I think you might find https://github.com/gwkkwg/cl-containers/blob/master/tests/test-containers.lisp#L142 relevant to your current situation
6:15:35
dim
your main immediate problem is providing an API that handles both push or replace a value for a given dictionnary key, right?
6:18:25
dim
well anyway good luck, my day is done. You seem to always have interesting problems to solve drmeister, have fun!
8:54:20
_death
[] is a terrible name.. there is an association between trying to ape other languages and envy of them
12:05:18
pjb
drmeister: you have 3 solutions: 1- wrap your (cdr (assoc key table :test 'string=)) in a functional abstraction. 2- intern those strings into some package (intern key "PYTHON-SYMBOL"). 3- internalize the strings themselves: (setf (gethash key *interned-strings*) key) with (defparmeter *interned-strings* (make-hash-table :test 'equal) or 'equalp for case insensitivity.
12:05:56
pjb
then (cdr (assoc (intern key "PYTHON-SYMBOLS" table))) or (cdr (assoc (gethash key *interned-strings* table)))
12:07:02
pjb
drmeister: it's rather trivial to write either a macro or a reader macro so that dict["a"] can be interpreted as ([] dict "a").
13:44:47
easye
Anyone know of any open concolic testing CL code <https://en.wikipedia.org/wiki/Concolic_testing>?
13:46:15
easye
err, the language tested doesn't have to be Common Lisp (actually I am interested in many others: JavaScript, EVM, etc.), but is there any concolic testing analysis expressed in CL?
14:31:15
phoe
drmeister: fun trivia, dict["a"] is an M-expression, which was the proposed syntax for Lisp back in the day
14:33:45
pjb
https://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/m-expression/index.html
15:41:09
gendl
Hi, any idea why asdf would suddenly start ignoring asdf/output-translations:*output-translations* ?