greg
2018-4-1 14:47:09

It’s not silly. But you have some other possibilities, too. Some are more commonly used, I think.


greg
2018-4-1 14:48:32
  • Return a single value, which is either a success value or an error value. In Racket docs you’ll see many functions return, say, (or/c number? #f). If #f among the valid success values, and/or if that’s too blunt, you could return symbols like 'error-foo 'error-bar to represent each kind of error. Regardless, it’s pretty easy to consume such functions using match.

greg
2018-4-1 14:49:07
  • Return multiple values instead of a list. I suppose if you want to force callers to deal with an error/success code as well as the usual value (is this like go-lang?? idk) then you could do this.

greg
2018-4-1 14:49:29
  • For an exceptional condition, throw an um exception.

greg
2018-4-1 14:51:35

Oh, one thing about what you said here: > the “natural” null of Lisp In many (most?) lisps, () or nil is falsey (for if etc.). But in Scheme and Racket, '() or null is truthy. i.e. There is no “nil punning” where the empty list means “false”.


greg
2018-4-1 14:52:13

The only false value (for if etc.) is #f (or an alias thereof like #false).


greg
2018-4-1 14:52:28

^ @slack1


slack1
2018-4-1 19:27:27

I think that’s good, because true and false are meant to be used in boolean contexts, and are also values


slack1
2018-4-1 19:27:33

but I wanted the concept of “empty”


lexi.lambda
2018-4-1 19:28:08

slack1
2018-4-1 19:37:33

oh I see, I was kind of talking about a “functor”


slack1
2018-4-1 19:37:41

wow, these docs explained that concept for the first time


slack1
2018-4-1 19:37:48

that was always an opaque word to me


slack1
2018-4-1 19:38:59

basically a type that admits an empty thing, and can have operations chained on due to its regular shape


slack1
2018-4-1 19:39:16

but it implies that once you eat a nothing type


slack1
2018-4-1 19:39:49

all following functions must expect it


slack1
2018-4-1 19:40:12

hm


slack1
2018-4-1 19:40:48

I have the intuition that once you have a “funny” condition in your app


slack1
2018-4-1 19:40:56

all functions in your app can be divided into two sorts


slack1
2018-4-1 19:41:04

the kind which has to check for the funny condition


slack1
2018-4-1 19:41:08

and the kind which doesn’t


slack1
2018-4-1 19:42:02

A functor sounds almost like a stream


slack1
2018-4-1 19:43:54

or to enjoy the maybe type


slack1
2018-4-1 19:43:59

every function must still check for it


lexi.lambda
2018-4-1 19:44:23

A functor is just a thing with a map operation for which (map identity x) is a no-op and (map (compose f g) x) is the same as (map f (map g x)), no more and no less, but the “container” metaphor is a useful one all the same. But in your case, I think the specific datatypes (maybe and either) are probably more interesting than the interfaces they implement.


lexi.lambda
2018-4-1 19:45:33

Generally, “every function must check for it” is an indication that you are doing something wrong, since you usually use data/monad to chain together operations that produce optional values and short-circuit if any of them fail.


lexi.lambda
2018-4-1 19:45:39

Alternatively, just use Racket exceptions.


slack1
2018-4-1 19:48:32

I think I have slightly more understanding;


slack1
2018-4-1 19:48:44

functions that return maybe types require a “framework” to operate around them


slack1
2018-4-1 19:48:48

and when they do


slack1
2018-4-1 19:48:57

you don’t have to double-check for empty


lexi.lambda
2018-4-1 19:49:13

Yes, that’s essentially right.


lexi.lambda
2018-4-1 19:49:58

The advantage of maybe or either over, say, exceptions, is that they are plain values, and you can do things like, for example, sticking them in a list.


lexi.lambda
2018-4-1 19:50:32

But if you aren’t doing anything like that, and you just have some operations that ought to fail and short-circuit the whole program (or a significant portion of the program), just use exceptions.


slack1
2018-4-1 19:51:12

I’m contemplating for a mini library


slack1
2018-4-1 19:51:17

so I am trying to avoid exceptions


slack1
2018-4-1 19:51:32

or I don’t know if people just expect it


slack1
2018-4-1 19:51:36

and so they won’t mind


lexi.lambda
2018-4-1 19:53:02

If it makes sense for a function to fail when given certain inputs, the idiomatic solution in Racket is to raise an exception. If the user is likely to want to regularly silence that exception, the idiomatic solution is to equip the function with an optional failure-thunk argument, such as the third argument to hash-ref. http://docs.racket-lang.org/reference/hashtables.html#%28def._%28%28quote._~23~25kernel%29._hash-ref%29%29