averellaquino
2020-6-11 08:59:22

@averellaquino has joined the channel


dbriemann
2020-6-11 12:13:18

Let’s say I have a class with fields a b and c but c is only sometimes set (data coming from an API that i do not control). Is it good style to set c to undefined ?


soegaard2
2020-6-11 12:14:36

Usually #f is used for that. At least If the value in question can’t be false.


dbriemann
2020-6-11 12:16:41

aha! thanks. that sounds good. I guess I am still in some kind of strong typing mindset where i was assuming that this can either be an int or “nothing” :slightly_smiling_face:


soegaard2
2020-6-11 12:17:56

Using #f allows you to write (when c …). Or perhaps (or c default-c) depending on the context.


dbriemann
2020-6-11 12:18:01

and then I can just check the value with if? and every integer would result in #t?


dbriemann
2020-6-11 12:18:10

ah ok


soegaard2
2020-6-11 12:18:23

Yes


dbriemann
2020-6-11 12:18:29

nice.. :slightly_smiling_face: thanks


dbriemann
2020-6-11 12:19:41

one last question (for now): so if I had that problem with booleans.. would i then choose undefined?


soegaard2
2020-6-11 12:24:08

Depends. Some functions use #f to mean no value and (lambda () #f) to mean #f. Let me see if I can dig up a better explanation / example.


dbriemann
2020-6-11 12:25:05

sure, no hurry. just trying to learn racket “right” :wink:


soegaard2
2020-6-11 12:26:12

(hash-ref! _hash_ _key_ _to-set_) > Returns the value for _key_ in _hash_. If no value is found for _key_, then _to-set_ determines the result as in https://docs.racket-lang.org/reference/hashtables.html?q=hash-ref#%28def._%28%28quote._~23~25kernel%29._hash-ref%29%29\|hash-ref  > (i.e., it is either a thunk that computes a value or a plain value), and this result is stored in _hash_ for the _key_. > (Note that if _to-set_ is a thunk, it is not invoked in tail position.)


soegaard2
2020-6-11 12:27:02

So here `to-set is the default value and it can be either a value or a thunk (function of 0 arguments) that return a value.


dbriemann
2020-6-11 12:28:57

ok yes i just looked at this a few days ago actually.


soegaard2
2020-6-11 12:59:32

Sometimes there are subtle differences between the usage of certain terms (from programming language to programming language.

In Racket undefined means that that a variable is declared but not yet initialized. Example: #lang racket (define x y) (define y 3) I can’t remember the undefined value being used for anything else.

On the other hand the absence of an optional argument doesn’t make the argument undefined (it’s just missing) - so the argument is given a default value.


badkins
2020-6-11 13:23:27

@dbriemann since you mentioned an API, if you ever need to get the data into a JSON object, then using 'null for a missing value is handy because the json library will convert that to null in JSON. But as @soegaard2 mentioned, using #f has some nice benefits.


samth
2020-6-11 13:32:22

@dbriemann in general, undefined is not something you use every intentionally. You can only access it using a binding named unsafe-undefined, and lots of things assume that no one has anything with that value intentionally.


sorawee
2020-6-11 13:43:33

Personally, I use this principle.

  1. If the data can’t be #f, then use #f to indicate absence of value
  2. If the data can be #f, then use (gensym) to create a unique symbol, and use this symbol to indicate absence of value.

sorawee
2020-6-11 13:45:37

Another possibility if the data can be #f but you can preprocess it, is to wrap it in a list. E.g., 1 -> (list 1). #f -> (list #f). Then, use either #f or empty list to indicate absence of value.


dbriemann
2020-6-11 13:52:15

thanks for all your information. is there something similar to ’null @badkins mentioned for sql usage? or do you have to do the mapping from object to table yourself anyways instead of something orm-like?


dbriemann
2020-6-11 13:54:33

doesn’t really matter now. I will look into racket and db later.. for now this #f default fits my use case very well


soegaard2
2020-6-11 13:55:28

I think you can use ’null with db. But you need to check.


dbriemann
2020-6-11 13:55:41

yea i got carried away.. one step after the other :slightly_smiling_face:


badkins
2020-6-11 14:11:40

@dbriemann the db library has a sql-null value


badkins
2020-6-11 14:15:43

@dbriemann here’s an example: ;; (db-maybe-date row idx) -> (or/c date? #f) ;; row : vector? ;; idx :: exact-nonnegative-integer? (define (db-maybe-date row idx) (let ([obj (vector-ref row idx)]) (if (sql-null? obj) #f (sql-date->date obj)))) w/ the corresponding write ;; (db-write-date obj) -> (or/c sql-date? sql-null?) ;; obj : date? (define (db-write-date obj) (if obj (date->sql-date obj) sql-null))


dbriemann
2020-6-11 14:18:03

thanks


badkins
2020-6-11 14:20:02

I’ve been working on a web framework which will encapsulate a lot of this stuff. Hope to release an alpha version by the end of the summer.


dbriemann
2020-6-11 14:20:58

interesting. will have a look then. what i currently do is all for desktop gui apps though.


badkins
2020-6-11 14:21:55

Gotcha. I’m hoping to make it very modular, so there may be some components you’d use such as the db interaction & utility functions.


code
2020-6-11 16:16:30

If have problems using the gen:indexable generics from data/collection. I get the error message: gen:indexable: generic method definition has an incorrect arity; expected a procedure that accepts 1 or more arguments ref: #<procedure:ref>


code
2020-6-11 16:16:54

this is a MVP code I am using #lang racket (require data/collection) (struct ash (h) #:methods gen:indexable [(define (ref collection index) (hash-ref (ash-h collection) index)) (define (set-ref collection index value) (hash-set (ash-h collection) index value))])


code
2020-6-11 16:17:18

This is assuming the struct gets passed a hash


samth
2020-6-11 16:19:35

it appears that gen:indexable requires functions that accept 1 and any number of additional arguments for both functions


samth
2020-6-11 16:19:40

cc @lexi.lambda


sorawee
2020-6-11 16:36:16

Here’s a workaround for now:

(struct ash (h) #:methods gen:indexable [(define (ref collection . args) (define index (first args)) (hash-ref (ash-h collection) index)) (define (set-ref collection . args) (match-define (list index value) args) (hash-set (ash-h collection) index value))])


sorawee
2020-6-11 16:39:31

Note that your set-ref probably should return an ash rather than a hash.


code
2020-6-11 16:50:06

thanks I got it working with your fix. Out of curiosity, where do I have to look to figure out the function needs a ‘rest’ argument?


samth
2020-6-11 16:51:42

I think you can’t tell from the docs — it’s just in the error message (“1 or more”). Looking at the docs, I expect this is a bug in the code.


code
2020-6-11 16:55:27

thank you, will open an issue on Github about this


anything
2020-6-12 00:32:12

I have to say this is a pretty nice idiom. I haven’t got used to it yet, though. I’ve read HtDP, so my writing above is what I go to when I’m in trouble. But I think in the future your style is unavoidable. I find it very nice the idea to suddenly define a function “loop” and call it a little ahead. Your let-arguments though are what I’m not quite used to doing. But I’ll get there. Thanks for your input. Very appreciated.


jcoo092
2020-6-12 04:29:54

I’m trying to use Typed Racket with a small regular-Racket program that I have (you can see the base version at https://github.com/jcoo092/CML_benchmarks/blob/master/Racket/src/commstime.rkt, if you want). I’m having a few problems, and I’m hoping someone can tell me how to deal with them :slightly_smiling_face:

  1. I thought I had to change (require racket/place) to (require typed/racket/place) to go along with #lang typed/racket/base, but when I do that, raco make complains that it can’t open the module file ‘typed/racket/place’. There doesn’t appear to be an issue when I stick with racket/place, but I don’t get the impression that is actually correct (?)
  2. When I stick with racket/place, I have a problem with the below function: (: ID (-&gt; Place-Channel Place-Channel Void)) (define (ID in out) ((place-channel-put out (place-channel-get in)) (ID in out))) I get an error message saying “Type Checker: Cannot apply expression of type Void, since it is not a function type”. I’m assuming that’s because my function is always recursive (it is run on a separate place, which is disposed of at the termination of the program), but I’m not sure how to get around this.
  3. I also get an error on (add1 (place-channel-get in)), viz “Type Checker: type mismatch expected: Number given: Any” which makes perfect sense to me, but I can’t figure out how to annotate the Place-Channel in the type definition to state that it should be a Place-Channel of Number only.

Any ideas?