freenode/#lisp - IRC Chatlog
Search
23:49:15
no-defun-allowed
how could i smooth off the alpha channel for cl-vep's background replacement function?
0:42:35
AeroNotix
regreg: unfortunately most of the "fun" work is done already. IIRC there's "libbilliards" that takes care of the majority of the ball physics
0:43:22
AeroNotix
I always wondered why there isn't a cheap over head table system that tracks ball positions. For match games where balls need to be reset (foul and a miss) then it's quite a manual job placing the balls back.
0:44:39
AeroNotix
Bike: that overhead table system I was mainly thinking about it being used in big matches. There's a rule in snooker which sometimes requires balls to be reset to their positions they were in before a foul.
0:45:08
AeroNotix
and it can take a lot of back and forth between replays to get the positions just right
0:45:32
AeroNotix
the balls are brightly coloured, the game is literally played on a green screen. Seems like it should be trivial
0:46:18
regreg
AeroNotix: if there are 4 games worth a $20million market, then with one extra good quality game you can take 1/5 of that market, meaning $4million, assuming your game quality is similar or better
0:47:16
AeroNotix
Bike: I was thinking using image processing of the state of the game play by play and use lasers to indicate older positions, if needed
0:48:27
AeroNotix
Bike: I wondered about putting something inside the balls but pros would be up in arms about stuff like that
0:50:30
AeroNotix
in other news my lisp z80 emulator can now run my z80 brainfuck interpreter code ;)
0:52:24
AeroNotix
I'm always looking for bigger and bigger roms to run on the emulator. I'm having isues assembling zexdoc/zexall with linux assemblers. Seems they're designed for ancient windows assemblers.
0:54:03
AeroNotix
indeed. There were loads of them behind the iron curtain. Clones and all sorts. All the way past the 32 bit era. People writing stuff like mortal combat for z80 based machines
0:55:08
AeroNotix
in my z80 emulator I have a plan (currently kind of almost working) where you can write a subset of CL that will compile to z80 machine code
0:57:32
AeroNotix
yeah. To be honest calling it a "subset of CL" is a bit strong. It's more "a shitty version of lisp"
0:58:53
AeroNotix
well, the z80 can by default access 64k of memory. I know in "my" version of lisp that this is oodles of memory, with plenty to spare for user programs
0:59:55
AeroNotix
The idea was just that you would define your own functions (+ a set that make sense built in) that compile directly to machine code
1:02:43
AeroNotix
vsync: it's just more complicated to create. With only a handful of chips you can create a useful z80 "computer"
1:04:13
AeroNotix
I need to actually get some hw. I've mostly been focused on creating the emulator and development tools
2:01:48
pjb
But notice that rename-package has "undefined consquences if new-name or any new-nickname conflicts with any existing package names."
2:02:13
pjb
I interpret that strictly, to mean that if there is already a package with the same name or nickname, rename-package can fail.
2:02:43
pjb
So I call it twice, using a temp name, like in com.informatimago.common-lisp.cesarum.package:add-nickname
2:03:11
pjb
But perhaps "nickname conflicts" are only when the name-package association is different?
2:04:17
pjb
In that case, removing a nickname could be done conformingly with (rename-package package (package-name package) (remove old-nickname (package-nicknames package)))
3:01:26
aeth
So normally I simplify something by making something a symbol or a list. i.e. in ((foo bar) (baz barfoo)) the first sublist binds bar to foo, but (foo (baz barfoo)) would bind foo to foo.
3:02:09
aeth
I can't do that in my particular case here, though, because I have (binding thing &key ...) instead of (binding thing)
3:02:45
aeth
The next best thing I can think of is having some symbol imply repetition, e.g. (foo * :some-key 42)
3:03:20
aeth
What symbol would be the most intuitive for not writing foo twice when I'm binding foo to the variable foo?
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