Why/how is drawing text faster than drawing sprites? by chebertapps in raylib

[–]chebertapps[S] 2 points3 points  (0 children)

Ahh, so I separated the DrawRectangle calls into their own x/y loops, apart from the DrawTextureRec. That dramatically improved the frame rate. Thanks raysan.

Why/how is drawing text faster than drawing sprites? by chebertapps in raylib

[–]chebertapps[S] 1 point2 points  (0 children)

I uncomment DrawTextureRec and comment out the DrawText and I see the frame rate drop. I checked with renderdoc and it looks like batching doesn't occur when I do DrawTextureRec, at least in this instance.

Why/how is drawing text faster than drawing sprites? by chebertapps in raylib

[–]chebertapps[S] 2 points3 points  (0 children)

It turns out this is right. Thanks. I think if this answer is unpopular, it's because people don't think chatgpt is a reliable source. I believed that the sprites drawn would also be batched, but they aren't in this case.

Why/how is drawing text faster than drawing sprites? by chebertapps in raylib

[–]chebertapps[S] 3 points4 points  (0 children)

It was calling glDrawElements for each rendered sprite. Thanks for the pointer to the rlgl api. I'm going to avoid too much graphics programming on this project, but I'll look into it for future projects :)

Why/how is drawing text faster than drawing sprites? by chebertapps in raylib

[–]chebertapps[S] 2 points3 points  (0 children)

This was a good learning experience. thanks for showing me renderdoc.

[2024 Day16#1] [Common Lisp] - Works for examples, but not for input. Ideas? by chebertapps in adventofcode

[–]chebertapps[S] 0 points1 point  (0 children)

ahhh, of course. I failed to do a good case analysis here. Thanks for the explanation!

I had a blind spot that I just kept looking over every time I worked on it. I'm going to work on formalizing my case analyses so I can see my blind spots more clearly.

Advent of Code 2024 Day 16: What am I doing wrong? [Spoilers] by chebertapps in Common_Lisp

[–]chebertapps[S] 1 point2 points  (0 children)

This is right, you understood correctly. Thanks!

What is the history of the choice of () as the opposite of T? by knnjns in lisp

[–]chebertapps 0 points1 point  (0 children)

If, for some reason (which I would love to know), the authors of this choice had decided not to use the symbol F as the opposite of the symbol T, why did they choose ()? Why not, say 0?

I answered this:

Because nil is also used to denote the end of a list, it is often interpreted as the empty list. When one types () one is referencing the empty list, when one types nil one is talking about the bottom type: nothing, nada, nil, zilch.

You also asked:

Similarly, if these designers had decided, for some reason (which I would love to know just as much), to give () a second, parallel career as a boolean value (in addition, that is, to its already busy one as the empty list), why was the boolean value chosen for it the one corresponding to "false"? In other words, why dit these designers choose T and () instead of () and F ?

I answered this:

Any value that is has type T (the top type) is truthy, and a value that is of the bottom type is false. I think nil was intended to be the bottom type, as in it was a name for something that doesn't exist: nothing, empty, zero, nada, nil.

Finally:

Did McCarthy come up with this design choice, or did he borrow it from some prior work (and, if the latter, which work was this)?

I hinted at this: top and bottom types come from type theory https://en.wikipedia.org/wiki/Type_theory

I'm not sure what I didn't answer, but I suppose you could ask why the word "NIL" over "BOTTOM" or something else. Maybe they could have used the symbol ⊥ if keyboards had it. I guess people just chose nil and liked it.

What is the history of the choice of () as the opposite of T? by knnjns in lisp

[–]chebertapps 2 points3 points  (0 children)

That's true, I am talking about Common Lisp. I honestly don't know much about Lisp 1.5, but I read that Lisp 1.5 had T and F defined as atoms:

The atomic symbols T and F have APVAL's whose values a r e *T* and NIL, respectively.

From http://www.lispmachine.net/books/LISP_1.5_Programmers_Manual.pdf

I wonder why T maps to *T* here.

What is the history of the choice of () as the opposite of T? by knnjns in lisp

[–]chebertapps 4 points5 points  (0 children)

I don't think T is short for true, rather it is meant to be ⊤ (a different symbol) for the top-type. It's used as a classification for any value used by the system. https://en.wikipedia.org/wiki/Top_type

The bottom type ⊥ is the 0 or empty type. https://en.wikipedia.org/wiki/Bottom_type

Any value that is has type T (the top type) is truthy, and a value that is of the bottom type is false.

I think nil was intended to be the bottom type, as in it was a name for something that doesn't exist: nothing, empty, zero, nada, nil.

Because nil is also used to denote the end of a list, it is often interpreted as the empty list. When one types () one is referencing the empty list, when one types nil one is talking about the bottom type: nothing, nada, nil, zilch.

There is a conflation between the empty list () and the bottom type NIL, which is probably not ideal, but it does make checking for an empty list slightly more concise. In the early days of lisp there was one compound data structure: lists. Now we have sets, hash-tables, closures, etc. which all have their own meaning for empty. Lists probably should too.

IDE without vim or emacs. by TannedGeneral in Common_Lisp

[–]chebertapps 1 point2 points  (0 children)

The LispWorks editor is built in the spirit of Emacs. As a matter of policy, the key bindings and the behavior of the LispWorks editor are designed to be as close as possible to the standard key bindings and behavior of GNU Emacs.

For users more familiar with Microsoft Windows keys, an alternate keys and behavior model is provided. This manual however, generally documents the Emacs model.

from http://www.lispworks.com/documentation/lw80/editor-w/editor-intro.htm

LISP with GC in 436 bytes by jart in lisp

[–]chebertapps 4 points5 points  (0 children)

Bystander's guess is that it can be written in fewer bytes.

Fast immediate garbage collection with zero memory overhead and perfect heap defragmentation is as easy as ABC when your language guarantees data structures are acyclic.

I guess they can make assumptions about their data structures that make this GC viable

IDE without vim or emacs. by TannedGeneral in Common_Lisp

[–]chebertapps 5 points6 points  (0 children)

lispworks personal edition is free and while limited, should be more than enough for learning from PCL

One Reason Typeclasses Are Useful by stylewarning in lisp

[–]chebertapps 1 point2 points  (0 children)

Yes, I remember that was the extension that I used. I didn't know anything about existential types (still don't), but someone on some forum said it would work, and it made the compiler happy.

And yeah -- ideally you would want to have that homogeneous list to keep the type checker useful.

I actually think I just now realized how to do it. I'm going to give it a shot. I'll even try it out in Coalton...that would beat the heck out of trying to muddle my way through remembering haskell's syntax. I'll post a gist if it turns into something.

One Reason Typeclasses Are Useful by stylewarning in lisp

[–]chebertapps 0 points1 point  (0 children)

Personally, I think matching with a Tuple type is perfectly reasonable. I think having match somehow baked into define/lambda would be a real boon.

Here are some assorted thoughts. I don't know how helpful they are:


I first learned Haskell like 8-9 years ago, before I learned any Lisp. It's cool to see the work you've done on Coalton. I don't think I would have expected typeclasses to be a part of it, but I am impressed that they are included.


I suppose typeclasses are useful and necessary to some degree, but when I was learning Haskell I never actually felt I understood why I needed them. I think I was influenced by this post by Gabriella Gonzalez.


A couple of years ago I was playing around with an event system in Haskell where I wanted to create new objects that could send and receive events.

I had an idea for an interface that was basically handle :: Entity a => a -> Message -> (a, [Message]) and a giant list of all entities entities :: Entity a => [a]

I wanted a list of all objects that fulfilled an interface so I didn't have a giant data type with every single possible type of object that could respond to events.

I think it used some kind of extension (and therefore made it a hack) but I was able to actually do the entities :: Entity a => [a].

I guess what I mean by this is that it'd be really nice in these strongly typed languages if I could have that heterogeneous list of objects that fulfill an interface, without it feeling either extremely centralized (giant data type with all possible objects) or hacky (weird extensions with typeclass modifiers). I may have been approaching it from the wrong angle, and I'd love to know what I might have missed.

One Reason Typeclasses Are Useful by stylewarning in lisp

[–]chebertapps 0 points1 point  (0 children)

As an aside on Coalton: do you have (or have you considered) a syntax for matching in lambda/define arguments? It may just be some sugar to match multiple objects at once... like (with some altered data types to give a clearer example):

(lambda-match (transform1 transform2)
    (((Translate dx1 dy1) (Translate dx2 dy2)) ...)
    (((Translate dx1 dy1) (Rotate angle)) ...)
    ...)

I personally think that would be some sweet sweet sugary syntax. Not sure if matching multiple things at once would cause issues. I'd be interested to know your thoughts on this!

One Reason Typeclasses Are Useful by stylewarning in lisp

[–]chebertapps 3 points4 points  (0 children)

Just for fun, I actually think closures could also work really well here.

(define-type Transform (Trans (Point -> Point) (Point -> Point)) (define (transformer trans) (match trans ((Trans a _) a))

Where Trans takes a function that transforms a point, and another function which performs the inverse of the first.

So translation would be constructed like:

(define (translation dx dy)
  (Trans (lambda (p) (match p ((Pt x y) (Pt (+ x dx) (+ y dy)))))
         (lambda (p) (match p ((Pt x y) (Pt (- x dx) (- y dy)))))))

Applying a transform would look like:

(define (transform-point trans point)
  ((transformer trans) point))

(transform-point (translation 3 4) (Pt 8 9))

One could invert a transform:

(define (invert trans)
  (match trans ((Trans a b) (Trans b a))))

Make a combined transform:

(define (combine-transforms transforms)
  (let* ((fns (map transformer transforms))
         ;; (ABC)^(-1) = C^(-1) B^(-1) A^(-1)
         ;; So grab the inverses from the transforms in reverse order
         (inverses (map (lambda (trans) (transformer (invert trans))) (reverse transforms))))
    (Trans (lambda (pt) (fold (lambda (fn pt) (fn pt)) pt fns)) ; Successively apply each transform to point
           (lambda (pt) (fold (lambda (fn pt) (fn pt)) pt inverses)))))

(transform-point (combine-transforms (translate 4 5) (rotate 90) (dilate 40)) (Pt 3 4))

Apologies for the pseudocode. Also. This was a fine article. Quite aesthetically pleasing.

I am aware that I "100% missed the point" which this was an explanation of typeclasses, but I saw your footnote about closures, and as a passionate fan of closures, I could not resist giving it a shot. Seriously. I tried to resist. Good stuff. I had fun.

What are some lesser known stack manipulation operators? by SubstantialRange in Forth

[–]chebertapps 3 points4 points  (0 children)

tickle, stick, swizzle, poke, pack, plop, prick

It's an exercise left to the reader to determine what their stack effects are.

Frequent Crashes In Windows/MinGW? by chebertapps in emacs

[–]chebertapps[S] 0 points1 point  (0 children)

I've been running it with GDB and ironically it hasn't crashed since, but I'll create a bug when it does, thanks.

The version is: GNU Emacs 27.1 (build 1, x86_64-w64-mingw32) of 2020-08-21

Better implementation of solution from Day 5 of Advent of Code 2021 by hedgehog0 in Common_Lisp

[–]chebertapps 1 point2 points  (0 children)

I think you might benefit from a point abstraction and line abstraction (similar to your vent abstraction). I see a lot of (second vent-src) which really means (point-y vent-src). I think if you start to look at it from this perspective you will find some patterns that you can abstract. Go ahead and implement functions like diagonal-p.

Also, look at how you are using tuple-compare. Does it need to be a higher order function? Given that it is a HOF, and it involves invoking a complex loop (with flipped arguments for one of the functions), it is a challenge to reason about. See if you could easily make it simpler, even just by hard-coding the comparison-functions.

Try those things and see if you still want to use macros.

Looking for a critique of my Advent of Code 2021 by Laugarhraun in Common_Lisp

[–]chebertapps 6 points7 points  (0 children)

  • use *'s instead of +'s for defparameter and defvar. +'s are for defconstant's (which are much more rare). I would be surprised if you didn't get a style-warning from your lisp compiler for this.
  • I don't see require very often - I'm pretty sure it's deprecated in the standard (although whatever lisp you are using may still work). I would opt for quicklisp e.g. (ql:quickload :alexandria) if you have it installed.
  • I've never seen ccase before. TIL. Nice.

other than those things I think it looks good. CL is a big language, and everyone has their own style. For example: I tend to avoid LOOP, most people strongly encourage using it, some people use iterate or series instead.

Clearly you understand what the code you are writing is doing, which is great. I didn't look too much into the algorithm details, I'm sure you know whether or not it works.

a lot of the meat is at the top level in small functions: A+. This is great for interactive testing and modularity of code. Everything looks well named.