Programming thread

  • 🐕 I am attempting to get the site runnning as fast as possible. If you are experiencing slow page load times, please report it.
What if true AGI can never come into existence due to some heretofore unseen reason? An enormous amount of capital will have been spent to arrive at that answer. Do they go ahead and brand it as True AI anyways
This already happened in December. According to Microsoft and OpenAI, they'll call any software that can grift $100 billion "AGI" - although the machine god of grift hasn't yet awoken.
https://www.businessinsider.com/microsoft-openai-put-price-tag-achieving-agi-2024-12
 
People hate LLMs (justifiably) but I'm hammered and just had some really interesting dialogue with DeepSeek:
Screenshot 2025-07-11 at 02-13-35 Arnold vs OJ in The Terminator - DeepSeek.webp
(And to think the nigger OJ Simpson (an actual killer) might have played the titular role)
 
Gentlemen of The Programming thread, it is my great pleasure to announce that I have finally, after 2 weeks of suffering and ripping my hair out, gotten the damned A* pathing algorithm to work in my program. It was a pain in the ass, and I have formed an uneasy ceasefire with the pointers, but I got it working. Glory glory hallelujah. Special thanks to my meatspace Homies(tm) for helping me out.
 
Look, even John Carmack had a hard time with SICP
It doesn't help that Scheme is kind of an abomination. I see the definition is up to R7RS by now, but I haven't really paid any attention to it since R5RS, and at that time, values and call-with-values were so awkward to use that few people did, and were in fact so little-used that when delay and force were added to the language, they were explicitly defined in terms of the value (singular) returned by an expression (presumably because the standards team had forgotten that it was possible for an expression to return multiple values), resulting in a pair of features that should be orthogonal but are instead mutually exclusive and force you to write a new macro (delay* expr) that expands into (delay (call-with-values (lambda () expr) list)) and to write a new function (force* promise) as (apply values (force promise)), just to get them to play well together. Don't believe me? Go read the reference implementations of delay and force on pages 32-33.
 
Gentlemen of The Programming thread, it is my great pleasure to announce that I have finally, after 2 weeks of suffering and ripping my hair out, gotten the damned A* pathing algorithm to work in my program. It was a pain in the ass, and I have formed an uneasy ceasefire with the pointers, but I got it working. Glory glory hallelujah. Special thanks to my meatspace Homies(tm) for helping me out.
Now realize you can optimize it further by searching from both ends and meet "in the middle"
It doesn't help that Scheme is kind of an abomination. I see the definition is up to R7RS by now, but I haven't really paid any attention to it since R5RS, and at that time, values and call-with-values were so awkward to use that few people did, and were in fact so little-used that when delay and force were added to the language, they were explicitly defined in terms of the value (singular) returned by an expression (presumably because the standards team had forgotten that it was possible for an expression to return multiple values), resulting in a pair of features that should be orthogonal but are instead mutually exclusive and force you to write a new macro (delay* expr) that expands into (delay (call-with-values (lambda () expr) list)) and to write a new function (force* promise) as (apply values (force promise)), just to get them to play well together. Don't believe me? Go read the reference implementations of delay and force on pages 32-33.
I know some of those words. Am I right in understanding that force evaluates a function defined through delay and then essentially "keeps" the value it returns and uses that value instead of the function on any further run? So any internal mutable state, like an internal counter, would get lost?
 
I know some of those words. Am I right in understanding that force evaluates a function defined through delay and then essentially "keeps" the value it returns and uses that value instead of the function on any further run? So any internal mutable state, like an internal counter, would get lost?
Pretty much. Delay creates a "promise" that wraps an expression, and the first time it gets passed to force, it is evaluated and the value is cached, so any later attempts to force the promise will return the cached value without having to repeat a potentially expensive computation. This allows Scheme, which uses call-by-value, to mimic "lazy" functional languages that use call-by-need. (It also allows for the creation of idempotent actions.)
 
  • Informative
Reactions: Anti Snigger
Pretty much. Delay creates a "promise" that wraps an expression, and the first time it gets passed to force, it is evaluated and the value is cached, so any later attempts to force the promise will return the cached value without having to repeat a potentially expensive computation. This allows Scheme, which uses call-by-value, to mimic "lazy" functional languages that use call-by-need. (It also allows for the creation of idempotent actions.)
So basically, force is storing a dict with the key being the reference to the function and the value being the returned value and looks that up, and if it doesn't find the right key it calls the function and adds it + the result to the dict? Seems less like lazy eval but rather more like memoization to me.
 
So basically, force is storing a dict with the key being the reference to the function and the value being the returned value and looks that up, and if it doesn't find the right key it calls the function and adds it + the result to the dict? Seems less like lazy eval but rather more like memoization to me.
I suppose it could do that if the hash table kept weak references to the keys to allow them to be garbage collected, but most implementations store the cached value in the promise itself, implemented as a data structure with three fields: a parameterless anonymous function that calculates the result, a boolean that records whether the value has been computed, and the cached result. Here's the reference implementation from the standard:

Code:
(define force
  (lambda (object)
    (object)))

(define-syntax delay
  (syntax-rules ()
    ((delay expression)
      (make-promise (lambda () expression)))))

(define make-promise
  (lambda (proc)
    (let ((result-ready? #f)
          (result #f))
      (lambda ()
        (if result-ready?
          result
          (let ((x (proc)))
            (if result-ready?
              result
              (begin (set! result-ready? #t)
                     (set! result x)
                     result))))))))
The odd-looking double check on result-ready? is necessary because it's possible to construct a self-referential promise that forces itself in the process of being forced and the once a value is cached it should not be replaced.
 
It doesn't help that Scheme is kind of an abomination. I see the definition is up to R7RS by now, but I haven't really paid any attention to it since R5RS, and at that time, values and call-with-values were so awkward to use that few people did, and were in fact so little-used that when delay and force were added to the language, they were explicitly defined in terms of the value (singular) returned by an expression (presumably because the standards team had forgotten that it was possible for an expression to return multiple values), resulting in a pair of features that should be orthogonal but are instead mutually exclusive and force you to write a new macro (delay* expr) that expands into (delay (call-with-values (lambda () expr) list)) and to write a new function (force* promise) as (apply values (force promise)), just to get them to play well together. Don't believe me? Go read the reference implementations of delay and force on pages 32-33.
SICP uses a very small subset of the language because it treats fundamental concepts, often including how to implement them. I don't think macros ever feature in SICP for instance - which makes the suckage of the Javascript version a feat, really. I think the reason experienced people struggle with SICP is that you can get surprisingly far for years and years without ever actually thinking formally about what you're doing, which is what SICP forces you to do.
 
Back