@samdphillips Could I ask what shallow typed is?
Raoul is shallow typing
(sorry for the stupid joke :smile: )
I sh’allow that pun :stuck_out_tongue_winking_eye:
Shalom!
I made packed vectors of element widths 2 & 4 in pure racket, analogue to data/bit-vector
. Questions: 1. Is there any interest in having a PR to add those to data
? 2. If so, should I format a PR fusing u2-vector
, u4-vector
and bit-vector
, keeping the existing path and interface unchanged for bit-vector
or keep them as separate modules? 3. Docs mention that fixnums have a platform-dependent bit width that to me seems to kill opportunities of making architecture-independent packed-vectors on a fixnum basis. However, maybe there would be interest for an architecture-dependent version?
Sounds useful. Maybe the mailing list is better?
I think it is kind of random, which libraries ended in data
and which did not.
Did you look at ffi/vector
?
@ryanc Yes, I did look at ffi/vector
and have no valid criticism. I just wanted everything in pure racket for a tool I’m building for myself. @soegaard2 Ok, perhaps you’re right about the mailing list. Will do.
(expt +nan.0 0) ; 1
(* 0 +nan.0) ; 0
:disappointed:
> " NaN, on the other hand, infects any calculation that involves it. Unless the calculation would produce the same result no matter what real value replaced NaN, the result is NaN." (* 0 (/ +inf.0 -inf.0)) ; 0
Yeah, well, I find this explanation unsatisfactory. It’s bitten me a few times already (in particular when doing symbolic calculations in rascas)
So I’m strongly considering making +nan.0 fully absorbing. To me, getting a +nan.0 anywhere means that something went horribly wrong somewhere.
I am scared to see, what racket-cas computes :slightly_smiling_face:
> (expand (normalize ’(* 0 (/ +inf.0 -inf.0)))) 0
> (expand (normalize ’(/ +inf.0 -inf.0))) +nan.0
Hmm.
NSpire:
That certainly makes more sense to me
It’s less surprising in any case
Agree.
What does Maxima do?
it seems that “inf” should be the positive infinity in maxima: https://maxima.sourceforge.io/docs/manual/maxima_18.html#Functions-and-Variables-for-Constants But: (%i9) 2 * inf;
(%o9) 2 inf
:confused:
That’s … odd.
I would also NaN
expect to be “infecting.” After all, NaN means "not a number", in which case “any number ^ 0 is 1” just doesn’t apply. Also, in practical terms, I’d rather want a “warning” in form of a NaN result, because it would most likely mean that the input data where the NaN in the exponentation came from was already wrong/unknown.
100% agree!
2 * inf. Ouch. ;-/
Probably I need to do something to make it treat inf
as infinity, I think it’s treating it as a mere symbol right now. Weird though
At least, it is consistent: > inf+inf 2 inf
Maybe the symbol inf needs to be imported?
I guess so
> Unfortunately, I have lost this implementation. I had a problem with my > hard disk and no backup of the code. But it is not difficult to > implement it again. I only need some time.
I get the same result (0) on my machine. I just suddenly lost faith in Maxima :disappointed:
I’ve added this test just to be sure: (check-equal? (- +inf.0 +inf.0) +nan.0)
:grin:
Given that there are different possible interpretations for +inf.0
, -inf.0
, and +nan.0
(and no one interpretation is useful for all applications), Racket has to pick a model that seems generally useful, consistent, and compatible with other libraries/implementations. Generally, +nan.0
is interpreted not as “something went wrong” but as “arbitrary unknown number”. (The “something went wrong” idea has been explored as signaling NaNs, of course, which Racket doesn’t try to implement.)
Meanwhile, having both 0
and 0.0
as distinct things is helpful, in that (* 0 +nan.0)
can be 0
while (* 0.0 +nan.0)
produces +nan.0
(on the grounds that 0
is exactly 0 while 0.0
is some number arbitrarily close to 0). The helpfulness of exact 0
kicks in when defining operations on complex numbers, where an exactly 0 imaginary part helps prevent infinites and not-a-numbers showing up unnecessarily. But you can use 0.0
to stay more in the floating-point world where +nan.0
s are more infectious. Even then, though, something (IEEE?) specifies that (expt +nan.0 0.0)
is 1.0
, so that’s what Racket does.
I agree, that Racket should follow IEEE. For symbolic algebra systems other choises makes sense.
@soegaard2 But since (in racket-cas) (expand '(* 0 a))
= 0, substituting a with +nan.0 will also make 0, even when (* +nan.0 0) is set to +nan.0
Yes, I need to change the value of (* 0 +nan.0)
@mflatt when I index symbols in the documentations (like <https://github.com/racket/racket/issues/1653#issuecomment–805453572|this one>), How can I change names of linked documentations?
I doubt that there’s currently a way to do that. Library names are only available for bindings, and probably only the containing document is available for a general indexed item. I don’t remember all the details, though. Index generation would be part of Scribble, while the search implementation is part of the “racket-index” package in racket/pkgs/racket-index/scribblings/main
.
I meant, even after fixing this, what should the following return? (subst (expand '(* 0 a)) 'a +nan.0)
This will be 0 if (* 0 a)
is simplified to 0, but: (subst '(* 0 a) 'a +nan.0) ; +nan.0
Note that ffi/vector is implemented in Racket
Wolfram Alpha says 0 for 0*x
though
Yes, they all do.
That is, I expect (subst (expand '(* 0 a)) 'a +nan.0)
to return 0. I expect a
to mean “a number” so it makes sense that 0*a
reduces to 0.
So the principle is “numeric over symbolic”. What about (* 0.0 x) and (* –0.0 x) ? Currently I’m leaving these as is
Leaving them makes sense if 0.0 is considered to be the positive ε.
Fwiw. Nspire: 0.*x ▸ 0.
Racket: (* 0.0 +inf.0) -> +nan.0, so 0.0 is not the positive ε
So (* 0.0 ’x) -> 0.0 makes sens then, I suppose
I expected to get the same in racket-cas, but got (* 0.0 x)
:disappointed:
haha :smile:
Nspire: 0.*∞ ▸ undef
I am sure 0.0*x worked at some point.
You should add a test case then :wink:
Wolfram Alpha: 2 * sum_{x=1}^\infty x^2
= \tilde{\infty} (infinity with undetermined complex phase) Same for y * sum_{x=1}^\infty x^2
I guess this is consistent with “Numeric over symbolic”. What does NSpire say?
Oh wait, @soegaard2 since Racket has both +0.0 and –0.0, why should (* x -0.0)
be reduced to -0.0
rather than +0.0
?
I’m trying to come up with a well-defined/formal principle for “Numeric over symbolic”. So far I have this: > If @racket[f] is a symbolic expression with @emph{n} free variables, > then if for all valid numeric values of these @emph{n} variables > (that do not lead to @racket[+nan.0] or to an exception being raised) > the expression reduces to a constant numeric value @emph{c}, > then rascas @emph{may} choose to eagerly reduce the expression @racket[f] > containing free variables to @emph{c}. But then the example above is not consistent with this. What do you think?
Thanks. I will check it out
If both +0.0 and –0.0 are present, and the sign of a real number x is unknown, then … 0.0*x can’t be reduced further.
Sure, but usually the sign of x
is unknown (or did you implement ‘assumptions’?)
If however one thinks of both +0.0 and –0.0 as representing inexact zero, then 0.0x = 0.0.
But we still need some consistency with Racket
No, I have thought about it. And yesterday, I had reason to read: https://www.maplesoft.com/support/help/maple/view.aspx?path=assume
Why do you need consistency in this case?
Because when you see the expression (* -3 -0.0)
I suppose you let Racket calculate the value?
True. I suppose, I didn’t give –0.0 much thought.
That’s precisely why I’m trying to come up with a clear principle, so as to be consistent and provide predictable results
I think, I’ll follow NSpire: −0.=0. ▸ true
but in racket eqv?
≠ =
:grin:
Yeah …
I am tempted to ban floating points :slightly_smiling_face:
(just kidding)
haha that would be fun :smile: > In Racket-CAS, pi does not have a numeric value and is represented by a program that calculates its exact value in the limit. The user can choose to terminate the computation at any point.
Hi, I’m having trouble getting mixins to work between the untyped and typed modules. Is this expected?
I’m trying #lang typed/racket/base
(module untyped racket/base
(require racket/class)
(provide my-mixin my-plain-mixin)
(define my-mixin
(mixin () ()
[init nodig]
(println nodig)
(super-new)))
(define my-plain-mixin
(mixin () ()
(super-new)
(define/public (test) 'hoi)))
;works
(new (my-mixin object%) [nodig "untyped"])
)
(module typed typed/racket/base
(require typed/racket/class)
(: typed-mixin (All (A #:row) (-> (Class #:row-var A) (Class #:row-var A [init [nodig String]]))))
(define (typed-mixin %)
(class %
[init nodig]
(println nodig)
(super-new)))
;works
(new (typed-mixin object%) [nodig "typed"])
)
(require typed/racket/class)
(require (submod "." typed))
(require/typed (submod "." untyped)
[my-mixin (All (A #:row)
(-> (Class #:row-var A)
(Class #:row-var A
[init [nodig String]])))]
[my-plain-mixin (All (A #:row)
(-> (Class #:row-var A)
(Class #:row-var A
[test (-> Symbol)])))])
;fails with 'unused initialization arguments'
(new (my-mixin object%) [nodig "mixed"])
;fails with 'superclass initialization not invoked'
(send (new (my-plain-mixin object%)) test)
@kedicode has joined the channel
Something like that should work.
There are a bunch of mixin examples in the tests. https://github.com/racket/typed-racket/blob/2876008ec7a16737c771d6360debe152163edaa5/typed-racket-test/succeed/sealing-contract-1.rkt\|https://github.com/racket/typed-racket/blob/2876008ec7a16737c771d6360debe152163edaa5/typed-racket-test/succeed/sealing-contract-1.rkt
@eibi_5000 has joined the channel
Hello, could you help me with the following exercise.
indicates which day of the week is with the date of birth
it’s on Dr Racket
Relatively new to Racket here; I wanted to dig into the source code of the language/the projects associated with it, so I tried to write a script that would clone all of the repositories under the Racket organization on GitHub onto my machine. After fighting with shell for a while, I found that the path of least resistance was to just use Racket: #lang racket
(require net/url json racket/runtime-path)
(define-runtime-path git-command "/bin/git")
(define (close-ports! in out err)
(close-output-port in)
(close-input-port out)
(close-input-port err))
(define (log-ports! out err)
(printf "~a" (port->string out))
(printf "~a" (port->string err)))
(define (git-clone! a-repo-url)
(define-values (sp out in err)
(subprocess
#f #f #f
git-command "clone" a-repo-url))
(subprocess-wait sp)
(log-ports! out err)
(close-ports! in out err))
(define (get-json! url-string)
(read-json (get-pure-port (string->url url-string))))
(define (get-repo-list json-expr)
(map (lambda (a-hash) (hash-ref a-hash 'ssh_url)) json-expr))
(define repo-urls
(get-repo-list
(append
(get-json! "<https://api.github.com/users/racket/repos?page=1&per_page=100>")
(get-json! "<https://api.github.com/users/racket/repos?page=2&per_page=100>"))))
(for-each git-clone! repo-urls)
A couple questions: 1. Is there a platform independent way to invoke git clone
? I don’t think using /bin/git
is very portable… 2. What’s the right way to test a script like this? Almost all of it seems super imperative and inherently messy (e.g., fetch stuff from the network and invoke a subprocess) and I’m not sure how to handle the side effects