Rename "NONE" to "none"

This commit is contained in:
Bruce Hill 2024-12-07 16:04:25 -05:00
parent a201939a81
commit 37f3e91f6c
33 changed files with 142 additions and 140 deletions

View File

@ -74,7 +74,7 @@ static bool promote(env_t *env, ast_t *ast, CORD *code, type_t *actual, type_t *
if (needed->tag == NumType && actual->tag == OptionalType && Match(actual, OptionalType)->type->tag == NumType) {
*code = CORD_all("({ ", compile_declaration(actual, "opt"), " = ", *code, "; ",
"if unlikely (", check_none(actual, "opt"), ")\n",
CORD_asprintf("fail_source(%r, %ld, %ld, \"This was expected to be a value, but it's NONE\");\n",
CORD_asprintf("fail_source(%r, %ld, %ld, \"This was expected to be a value, but it's none\");\n",
CORD_quoted(ast->file->filename),
(long)(ast->start - ast->file->text),
(long)(ast->end - ast->file->text)),
@ -470,7 +470,7 @@ static CORD compile_condition(env_t *env, ast_t *ast)
} else if (t->tag == OptionalType) {
return CORD_all("!", check_none(t, compile(env, ast)));
} else if (t->tag == PointerType) {
code_err(ast, "This pointer will always be non-NONE, so it should not be used in a conditional.");
code_err(ast, "This pointer will always be non-none, so it should not be used in a conditional.");
} else {
code_err(ast, "%T values cannot be used for conditionals", t);
}
@ -1991,7 +1991,7 @@ CORD compile_none(type_t *t)
env_t *enum_env = Match(t, EnumType)->env;
return CORD_all("((", compile_type(t), "){", namespace_prefix(enum_env, enum_env->namespace), "null})");
}
default: compiler_err(NULL, NULL, NULL, "NONE isn't implemented for this type: %T", t);
default: compiler_err(NULL, NULL, NULL, "none isn't implemented for this type: %T", t);
}
}
@ -2033,7 +2033,7 @@ CORD compile(env_t *env, ast_t *ast)
switch (ast->tag) {
case None: {
if (!Match(ast, None)->type)
code_err(ast, "This 'NONE' needs to specify what type it is using `NONE:Type` syntax");
code_err(ast, "This 'none' needs to specify what type it is using `none:Type` syntax");
type_t *t = parse_type_ast(env, Match(ast, None)->type);
return compile_none(t);
}
@ -2122,7 +2122,7 @@ CORD compile(env_t *env, ast_t *ast)
CORD value_code = compile(env, value);
return CORD_all("({ ", compile_declaration(t, "opt"), " = ", value_code, "; ",
"if unlikely (", check_none(t, "opt"), ")\n",
CORD_asprintf("fail_source(%r, %ld, %ld, \"This was expected to be a value, but it's NONE\");\n",
CORD_asprintf("fail_source(%r, %ld, %ld, \"This was expected to be a value, but it's none\");\n",
CORD_quoted(ast->file->filename),
(long)(value->start - value->file->text),
(long)(value->end - value->file->text)),

View File

@ -366,7 +366,7 @@ The index of the first occurrence or `!Int` if not found.
= 2 : Int?
>> [10, 20, 30, 40, 50]:find(9999)
= NONE : Int?
= none : Int?
```
---
@ -396,7 +396,7 @@ item matches.
>> [4, 5, 6]:find(func(i:&Int): i:is_prime())
= 5 : Int?
>> [4, 6, 8]:find(func(i:&Int): i:is_prime())
= NONE : Int?
= none : Int?
```
---

View File

@ -33,5 +33,5 @@ func parse(text: Text -> Bool?)
>> Bool.parse("no")
= no : Bool?
>> Bool.parse("???")
= NONE : Bool?
= none : Bool?
```

View File

@ -220,7 +220,7 @@ func parse(text: Text -> Int?)
**Returns:**
The integer represented by the text. If the given text contains a value outside
of the representable range or if the entire text can't be parsed as an integer,
`NONE` will be returned.
`none` will be returned.
**Example:**
```tomo
@ -231,11 +231,11 @@ of the representable range or if the entire text can't be parsed as an integer,
# Can't parse:
>> Int.parse("asdf")
= NONE : Int?
= none : Int?
# Outside valid range:
>> Int8.parse("9999999")
= NONE : Int8?
= none : Int8?
```
---

View File

@ -22,7 +22,7 @@ successively gets one line from a file at a time until the file is exhausted:
>> iter()
= "line three" : Text?
>> iter()
= NONE : Text?
= none : Text?
for line in (./test.txt):each_line():
pass

View File

@ -6,7 +6,7 @@ behavior that is required for all types:
- `func as_text(obj:&T?, colorize=no, type:&TypeInfo_t -> Text)`: a method to
convert the type to a string. If `colorize` is `yes`, then the method should
include ANSI escape codes for syntax highlighting. If the `obj` pointer is
`NONE`, a string representation of the type will be returned instead.
`none`, a string representation of the type will be returned instead.
- `func compare(x:&T, y:&T, type:&TypeInfo_t -> Int32)`: Return an integer representing
the result of comparing `x` and `y`, where negative numbers mean `x` is less

View File

@ -523,7 +523,7 @@ Returns a `Moment` object representing the current date and time.
**Description:**
Return a new `Moment` object parsed from the given string in the given format,
or `NONE` if the value could not be successfully parsed.
or `none` if the value could not be successfully parsed.
**Signature:**
```tomo
@ -539,7 +539,7 @@ func parse(text: Text, format: Text = "%Y-%m-%dT%H:%M:%S%z" -> Moment?)
**Returns:**
If the text was successfully parsed according to the given format, return a
`Moment` representing that information. Otherwise, return `NONE`.
`Moment` representing that information. Otherwise, return `none`.
**Example:**
```tomo

View File

@ -26,7 +26,7 @@ differentiate between possibly-NaN values and definitely-not-NaN values.
Tomo has a separate concept for expressing the lack of a defined value:
optional types. Consequently, Tomo has merged these two concepts, so `NaN` is
called `NONE` and has the type `Num?` or `Num32?`. In this way, it's no
called `none` and has the type `Num?` or `Num32?`. In this way, it's no
different from optional integers or optional arrays. This means that if a
variable has type `Num`, it is guaranteed to not hold a NaN value. This also
means that operations which may produce NaN values have a result type of
@ -36,9 +36,9 @@ values (zero times infinity), and many math functions like `sqrt()` can return
NaN for some inputs.
Unfortunately, one of the big downsides of optional types is that explicit
`NONE` handling can be very verbose. To make Nums actually usable, Tomo applies
very liberal use of type coercion and implicit `NONE` checks when values are
required to be non-NONE. Here are a few examples:
`none` handling can be very verbose. To make Nums actually usable, Tomo applies
very liberal use of type coercion and implicit `none` checks when values are
required to be non-none. Here are a few examples:
```tomo
>> x := 0.0
@ -46,17 +46,17 @@ required to be non-NONE. Here are a few examples:
y := 1.0
# Division might produce NONE:
# Division might produce none:
>> x / y
= 0 : Num?
>> x / x
= NONE : Num?
= none : Num?
# Optional types and NONE values propagate:
# Optional types and none values propagate:
>> x/y + 1 + 2
= 3 : Num?
>> x/x + 1 + 2
= NONE : Num?
= none : Num?
# Optional Nums can be handled explicitly using `or` and `!`:
>> x/x or -123
@ -66,18 +66,18 @@ y := 1.0
>> (x/y)!
= 0 : Num
# Assigning to a non-optional variable will do an implicit check for NONE and
# raise a runtime error if the value is NONE, essentially the same as an
# Assigning to a non-optional variable will do an implicit check for none and
# raise a runtime error if the value is none, essentially the same as an
# implicit `!`:
x = x/y
func doop(x:Num -> Num):
# If a function's return type is non-optional and an optional value is
# used in a return statement, an implicit NONE check will be inserted and
# will error if the value is NONE:
# used in a return statement, an implicit none check will be inserted and
# will error if the value is none:
return x / 2
# Function arguments are also implicitly checked for NONE if the given value
# Function arguments are also implicitly checked for none if the given value
# is optional and the function needs a non-optional value:
>> doop(x/y)
= 0 : Num
@ -665,7 +665,7 @@ func parse(text: Text -> Num?)
- `text`: The text containing the number.
**Returns:**
The number represented by the text or `NONE` if the entire text can't be parsed
The number represented by the text or `none` if the entire text can't be parsed
as a number.
**Example:**

View File

@ -35,12 +35,12 @@ Optional types are written using a `?` after the type name. So, an optional
integer would be written as `Int?` and an optional array of texts would be
written as `[Text]?`.
None can be written explicitly using `NONE` with a type annotation. For
None can be written explicitly using `none` with a type annotation. For
example, if you wanted to declare a variable that could be either an integer
value or `NONE` and initialize it as none, you would write it as:
value or `none` and initialize it as none, you would write it as:
```tomo
x := NONE:Int
x := none:Int
```
Similarly, if you wanted to declare a variable that could be an array of texts
@ -51,7 +51,7 @@ x := ![Text]
```
If you want to declare a variable and initialize it with a non-none value, but
keep open the possibility of assigning `NONE` later, you can use the postfix
keep open the possibility of assigning `none` later, you can use the postfix
`?` operator to indicate that a value is optional:
```tomo
@ -62,7 +62,7 @@ x = !Int
## Type Inference
For convenience, `NONE` can also be written without the explicit type
For convenience, `none` can also be written without the explicit type
annotation for any type in situations where the compiler knows what type of
optional value is expected:
@ -74,12 +74,12 @@ Here are some examples:
```tomo
x := 5?
x = NONE
x = none
func doop(arg:Int?)->Text?:
return NONE
return none
doop(NONE)
doop(none)
```
Non-none values can also be automatically promoted to optional values without
@ -97,7 +97,7 @@ doop(123)
## None Checking
In addition to using conditionals to check for `NONE`, you can also use `or` to
In addition to using conditionals to check for `none`, you can also use `or` to
get a non-none value by either providing an alternative non-none value or by
providing an early out statement like `return`/`skip`/`stop` or a function with
an `Abort` type like `fail()` or `exit()`:

View File

@ -495,7 +495,7 @@ raised.
= "Hello" : Text?
>> (./nosuchfile.xxx):read()
= NONE : Text?
= none : Text?
```
---
@ -524,7 +524,7 @@ returned.
= [72[B], 101[B], 108[B], 108[B], 111[B]] : [Byte]?
>> (./nosuchfile.xxx):read()
= NONE : [Byte]?
= none : [Byte]?
```
---

View File

@ -22,7 +22,7 @@ nums := [:Int]
sum := (+: nums)
>> sum
= NONE : Int?
= none : Int?
>> sum or 0
= 0

View File

@ -52,7 +52,7 @@ cyclic datastructures correctly, enabling you to serialize cyclic structures
like circularly linked lists or graphs:
```tomo
struct Cycle(name:Text, next=NONE:@Cycle)
struct Cycle(name:Text, next=none:@Cycle)
c := @Cycle("A")
c.next = @Cycle("B", next=c)

View File

@ -43,12 +43,12 @@ table := {"A": 1, "B": 2}
>> table["A"]
= 1 : Int?
>> table["missing"]
= NONE : Int?
= none : Int?
```
As with all optional values, you can use the `!` postfix operator to assert
that the value is non-NONE (and create a runtime error if it is), or you can
use the `or` operator to provide a fallback value in the case that it's NONE:
that the value is non-none (and create a runtime error if it is), or you can
use the `or` operator to provide a fallback value in the case that it's none:
```tomo
>> table["A"]!
@ -77,7 +77,7 @@ table value:
>> t2.fallback
= {"A":10} : {Text:Int}?
>> t.fallback
= NONE : {Text:Int}?
= none : {Text:Int}?
```
## Setting Values
@ -213,7 +213,7 @@ The value associated with the key or null if the key is not found.
= 1 : Int?
>> t:get("????")
= NONE : Int?
= none : Int?
>> t:get("A")!
= 1 : Int

View File

@ -695,9 +695,9 @@ containing information about the match.
**Example:**
```tomo
>> " #one #two #three ":find($/#{id}/, start=-999)
= NONE : Match?
= none : Match?
>> " #one #two #three ":find($/#{id}/, start=999)
= NONE : Match?
= none : Match?
>> " #one #two #three ":find($/#{id}/)
= Match(text="#one", index=2, captures=["one"]) : Match?
>> " #one #two #three ":find("{id}", start=6)
@ -887,7 +887,7 @@ or a null value otherwise.
**Example:**
```tomo
>> "hello world":matches($/{id}/)
= NONE : [Text]?
= none : [Text]?
>> "hello world":matches($/{id} {id}/)
= ["hello", "world"] : [Text]?

View File

@ -293,29 +293,29 @@ env_t *new_compilation_unit(CORD libname)
// Used as a default for functions below:
{"now", "Moment$now", "func(->Moment)"},
{"after", "Moment$after", "func(moment:Moment,seconds,minutes,hours=0.0,days,weeks,months,years=0,timezone=NONE:Text -> Moment)"},
{"date", "Moment$date", "func(moment:Moment,timezone=NONE:Text -> Text)"},
{"day_of_month", "Moment$day_of_month", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"day_of_week", "Moment$day_of_week", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"day_of_year", "Moment$day_of_year", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"format", "Moment$format", "func(moment:Moment,format=\"%Y-%m-%dT%H:%M:%S%z\",timezone=NONE:Text -> Text)"},
{"after", "Moment$after", "func(moment:Moment,seconds,minutes,hours=0.0,days,weeks,months,years=0,timezone=none:Text -> Moment)"},
{"date", "Moment$date", "func(moment:Moment,timezone=none:Text -> Text)"},
{"day_of_month", "Moment$day_of_month", "func(moment:Moment,timezone=none:Text -> Int)"},
{"day_of_week", "Moment$day_of_week", "func(moment:Moment,timezone=none:Text -> Int)"},
{"day_of_year", "Moment$day_of_year", "func(moment:Moment,timezone=none:Text -> Int)"},
{"format", "Moment$format", "func(moment:Moment,format=\"%Y-%m-%dT%H:%M:%S%z\",timezone=none:Text -> Text)"},
{"from_unix_timestamp", "Moment$from_unix_timestamp", "func(timestamp:Int64 -> Moment)"},
{"get_local_timezone", "Moment$get_local_timezone", "func(->Text)"},
{"hour", "Moment$hour", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"hour", "Moment$hour", "func(moment:Moment,timezone=none:Text -> Int)"},
{"hours_till", "Moment$hours_till", "func(now,then:Moment -> Num)"},
{"minute", "Moment$minute", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"minute", "Moment$minute", "func(moment:Moment,timezone=none:Text -> Int)"},
{"minutes_till", "Moment$minutes_till", "func(now,then:Moment -> Num)"},
{"month", "Moment$month", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"microsecond", "Moment$microsecond", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"new", "Moment$new", "func(year,month,day:Int,hour,minute=0,second=0.0,timezone=NONE:Text -> Moment)"},
{"month", "Moment$month", "func(moment:Moment,timezone=none:Text -> Int)"},
{"microsecond", "Moment$microsecond", "func(moment:Moment,timezone=none:Text -> Int)"},
{"new", "Moment$new", "func(year,month,day:Int,hour,minute=0,second=0.0,timezone=none:Text -> Moment)"},
{"parse", "Moment$parse", "func(text:Text, format=\"%Y-%m-%dT%H:%M:%S%z\" -> Moment?)"},
{"relative", "Moment$relative", "func(moment:Moment,relative_to=Moment.now(),timezone=NONE:Text -> Text)"},
{"second", "Moment$second", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"relative", "Moment$relative", "func(moment:Moment,relative_to=Moment.now(),timezone=none:Text -> Text)"},
{"second", "Moment$second", "func(moment:Moment,timezone=none:Text -> Int)"},
{"seconds_till", "Moment$seconds_till", "func(now:Moment,then:Moment -> Num)"},
{"set_local_timezone", "Moment$set_local_timezone", "func(timezone=NONE:Text)"},
{"time", "Moment$time", "func(moment:Moment,seconds=no,am_pm=yes,timezone=NONE:Text -> Text)"},
{"set_local_timezone", "Moment$set_local_timezone", "func(timezone=none:Text)"},
{"time", "Moment$time", "func(moment:Moment,seconds=no,am_pm=yes,timezone=none:Text -> Text)"},
{"unix_timestamp", "Moment$unix_timestamp", "func(moment:Moment -> Int64)"},
{"year", "Moment$year", "func(moment:Moment,timezone=NONE:Text -> Int)"},
{"year", "Moment$year", "func(moment:Moment,timezone=none:Text -> Int)"},
)},
{"Path", Type(TextType, .lang="Path", .env=namespace_env(env, "Path")), "Text_t", "Text$info", TypedArray(ns_entry_t,
{"append", "Path$append", "func(path:Path, text:Text, permissions=Int32(0o644))"},
@ -338,7 +338,7 @@ env_t *new_compilation_unit(CORD libname)
{"is_symlink", "Path$is_symlink", "func(path:Path -> Bool)"},
{"parent", "Path$parent", "func(path:Path -> Path)"},
{"read", "Path$read", "func(path:Path -> Text?)"},
{"read_bytes", "Path$read_bytes", "func(path:Path, limit=NONE:Int -> [Byte]?)"},
{"read_bytes", "Path$read_bytes", "func(path:Path, limit=none:Int -> [Byte]?)"},
{"relative", "Path$relative", "func(path:Path, relative_to=(./) -> Path)"},
{"remove", "Path$remove", "func(path:Path, ignore_missing=no)"},
{"resolved", "Path$resolved", "func(path:Path, relative_to=(./) -> Path)"},

View File

@ -59,10 +59,10 @@ lang Base64:
output[dest+2] = _EQUAL_BYTE
output[dest+3] = _EQUAL_BYTE
return Base64.without_escaping(Text.from_bytes(output) or return NONE)
return Base64.without_escaping(Text.from_bytes(output) or return none)
func decode_text(b64:Base64 -> Text?):
return Text.from_bytes(b64:decode_bytes() or return NONE)
return Text.from_bytes(b64:decode_bytes() or return none)
func decode_bytes(b64:Base64 -> [Byte]?):
bytes := b64.text_content:bytes()

View File

@ -78,7 +78,7 @@ func _send(method:_Method, url:Text, data:Text?, headers=[:Text] -> HTTPResponse
return HTTPResponse(Int(code), "":join(chunks))
func get(url:Text, headers=[:Text] -> HTTPResponse):
return _send(GET, url, NONE, headers)
return _send(GET, url, none, headers)
func post(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"] -> HTTPResponse):
return _send(POST, url, data, headers)
@ -89,7 +89,7 @@ func put(url:Text, data="", headers=["Content-Type: application/json", "Accept:
func patch(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"] -> HTTPResponse):
return _send(PATCH, url, data, headers)
func delete(url:Text, data=NONE:Text, headers=["Content-Type: application/json", "Accept: application/json"] -> HTTPResponse):
func delete(url:Text, data=none:Text, headers=["Content-Type: application/json", "Accept: application/json"] -> HTTPResponse):
return _send(DELETE, url, data, headers)
func main():

View File

@ -108,17 +108,17 @@ func main():
>> table["two"]
= 2 : Int?
# The value returned is optional because NONE will be returned if the key
# The value returned is optional because none will be returned if the key
# is not in the table:
>> table["xxx"]!
= NONE : Int?
= none : Int?
# Optional values can be converted to regular values using `!` (which will
# create a runtime error if the value is null):
>> table["two"]!
= 2 : Int
# You can also use `or` to provide a fallback value to replace NONE:
# You can also use `or` to provide a fallback value to replace none:
>> table["xxx"] or 0
= 0 : Int

View File

@ -85,7 +85,7 @@ func main():
t := PThread.new(func():
say("In another thread!")
item := @NONE:Int
item := @none:Int
while item[] != 30:
g:guarded(func():
while queue.length == 0:

View File

@ -38,7 +38,7 @@ func main(paths:[Path]):
say("Already installed: $url")
skip
alias := NONE:Text
alias := none:Text
curl_flags := ["-L"]
if github := url_without_protocol:matches($|github.com/{!/}/{!/}#{..}|):
user := github[1]

View File

@ -53,7 +53,7 @@ int op_tightness[] = {
static const char *keywords[] = {
"yes", "xor", "while", "when", "use", "unless", "struct", "stop", "skip", "return",
"or", "not", "no", "mod1", "mod", "pass", "lang", "inline", "in", "if",
"func", "for", "extern", "enum", "else", "do", "deserialize", "defer", "and", "NONE",
"func", "for", "extern", "enum", "else", "do", "deserialize", "defer", "and", "none",
"_min_", "_max_", NULL,
};
@ -1545,7 +1545,7 @@ PARSER(parse_lambda) {
PARSER(parse_none) {
const char *start = pos;
if (!match_word(&pos, "NONE"))
if (!match_word(&pos, "none"))
return NULL;
const char *none_end = pos;

View File

@ -53,7 +53,7 @@ public Text_t Optional$as_text(const void *obj, bool colorize, const TypeInfo_t
return Text$concat(generic_as_text(obj, colorize, type->OptionalInfo.type), Text("?"));
if (is_none(obj, type->OptionalInfo.type))
return colorize ? Text("\x1b[31mNONE\x1b[m") : Text("NONE");
return colorize ? Text("\x1b[31mnone\x1b[m") : Text("none");
return generic_as_text(obj, colorize, type->OptionalInfo.type);
}

View File

@ -162,9 +162,9 @@ func main():
>> ["a", "b", "c"]:find("b")
= 2 : Int?
>> ["a", "b", "c"]:find("XXX")
= NONE : Int?
= none : Int?
>> [10, 20]:first(func(i:&Int): i:is_prime())
= NONE : Int?
= none : Int?
>> [4, 5, 6]:first(func(i:&Int): i:is_prime())
= 2 : Int?

View File

@ -4,7 +4,7 @@ struct Pair(x:Text, y:Text)
func pairwise(strs:[Text] -> func(->Pair?)):
i := 1
return func():
if i + 1 > strs.length: return NONE:Pair
if i + 1 > strs.length: return none:Pair
i += 1
return Pair(strs[i-1], strs[i])?
@ -12,7 +12,7 @@ func range(first:Int, last:Int -> func(->Int?)):
i := first
return func():
if i > last:
return NONE:Int
return none:Int
i += 1
return (i-1)?

View File

@ -22,8 +22,8 @@ func main():
>> Num.INF:isinf()
= yes
>> nan := NONE : Num
= NONE : Num?
>> nan := none : Num
= none : Num?
>> nan == nan
= yes
>> nan < nan
@ -46,10 +46,10 @@ func main():
= -1
>> nan + 1
= NONE : Num?
= none : Num?
>> 0./0.
= NONE : Num?
= none : Num?
>> Num.PI:cos()!:near(-1)
= yes

View File

@ -4,81 +4,81 @@ struct Struct(x:Int, y:Text):
if should_i:
return Struct(123, "hello")
else:
return NONE
return none
enum Enum(X, Y(y:Int)):
func maybe(should_i:Bool->Enum?):
if should_i:
return Enum.Y(123)
else:
return NONE
return none
func maybe_int(should_i:Bool->Int?):
if should_i:
return 123
else:
return NONE
return none
func maybe_int64(should_i:Bool->Int64?):
if should_i:
return Int64(123)
else:
return NONE
return none
func maybe_array(should_i:Bool->[Int]?):
if should_i:
return [10, 20, 30]
else:
return NONE
return none
func maybe_bool(should_i:Bool->Bool?):
if should_i:
return no
else:
return NONE
return none
func maybe_text(should_i:Bool->Text?):
if should_i:
return "Hello"
else:
return NONE
return none
func maybe_num(should_i:Bool->Num?):
if should_i:
return 12.3
else:
return NONE
return none
func maybe_lambda(should_i:Bool-> func()?):
if should_i:
return func(): say("hi!")
else:
return NONE
return none
func maybe_c_string(should_i:Bool->CString?):
if should_i:
return ("hi":as_c_string())?
else:
return NONE
return none
func maybe_channel(should_i:Bool->|Int|?):
if should_i:
return |:Int|?
else:
return NONE
return none
func maybe_thread(should_i:Bool->Thread?):
if should_i:
return Thread.new(func(): pass)
else:
return NONE
return none
func main():
>> 5?
= 5 : Int?
>> if no:
NONE:Int
none:Int
else:
5
= 5 : Int?
@ -92,7 +92,7 @@ func main():
>> 5? or exit("Non-null is falsey")
= 5 : Int
>> (NONE:Int) or -1
>> (none:Int) or -1
= -1 : Int
do:
@ -100,7 +100,7 @@ func main():
>> yep := maybe_int(yes)
= 123 : Int?
>> nope := maybe_int(no)
= NONE : Int?
= none : Int?
>> if yep:
>> yep
= 123
@ -115,7 +115,7 @@ func main():
>> yep := maybe_int64(yes)
= 123 : Int64?
>> nope := maybe_int64(no)
= NONE : Int64?
= none : Int64?
>> if yep:
>> yep
= 123
@ -130,7 +130,7 @@ func main():
>> yep := maybe_array(yes)
= [10, 20, 30] : [Int]?
>> nope := maybe_array(no)
= NONE : [Int]?
= none : [Int]?
>> if yep:
>> yep
= [10, 20, 30]
@ -145,7 +145,7 @@ func main():
>> yep := maybe_bool(yes)
= no : Bool?
>> nope := maybe_bool(no)
= NONE : Bool?
= none : Bool?
>> if yep:
>> yep
= no
@ -160,7 +160,7 @@ func main():
>> yep := maybe_text(yes)
= "Hello" : Text?
>> nope := maybe_text(no)
= NONE : Text?
= none : Text?
>> if yep:
>> yep
= "Hello"
@ -175,7 +175,7 @@ func main():
>> yep := maybe_num(yes)
= 12.3 : Num?
>> nope := maybe_num(no)
= NONE : Num?
= none : Num?
>> if yep:
>> yep
= 12.3
@ -190,7 +190,7 @@ func main():
>> yep := maybe_lambda(yes)
= func() [optionals.tm:54] : func()?
>> nope := maybe_lambda(no)
= NONE : func()?
= none : func()?
>> if yep:
>> yep
= func() [optionals.tm:54]
@ -205,7 +205,7 @@ func main():
>> yep := Struct.maybe(yes)
= Struct(x=123, y="hello") : Struct?
>> nope := Struct.maybe(no)
= NONE : Struct?
= none : Struct?
>> if yep:
>> yep
= Struct(x=123, y="hello")
@ -220,7 +220,7 @@ func main():
>> yep := Enum.maybe(yes)
= Enum.Y(123) : Enum?
>> nope := Enum.maybe(no)
= NONE : Enum?
= none : Enum?
>> if yep:
>> yep
= Enum.Y(123)
@ -235,7 +235,7 @@ func main():
>> yep := maybe_c_string(yes)
= CString("hi") : CString?
>> nope := maybe_c_string(no)
= NONE : CString?
= none : CString?
>> if yep:
>> yep
= CString("hi")
@ -250,7 +250,7 @@ func main():
>> yep := maybe_channel(yes)
# No "=" test here because channels use addresses in the text version
>> nope := maybe_channel(no)
= NONE : |:Int|?
= none : |:Int|?
>> if yep: >> yep
else: fail("Falsey: $yep")
>> if nope:
@ -263,7 +263,7 @@ func main():
>> yep := maybe_thread(yes)
# No "=" test here because threads use addresses in the text version
>> nope := maybe_thread(no)
= NONE : Thread?
= none : Thread?
>> if yep: >> yep
else: fail("Falsey: $yep")
>> if nope:
@ -279,14 +279,16 @@ func main():
= 123 : Int
# Test comparisons, hashing, equality:
>> (NONE:Int == 5?)
>> (none:Int == 5?)
= no
>> (5? == 5?)
= yes
>> {NONE:Int, NONE:Int}
= {NONE}
>> [5?, NONE:Int, NONE:Int, 6?]:sorted()
= [NONE, NONE, 5, 6]
>> {none:Int, none:Int}
= {none}
>> {:Int? none, none}
= {none}
>> [5?, none:Int, none:Int, 6?]:sorted()
= [none, none, 5, 6]
do:
>> value := if var := 5?:
@ -296,7 +298,7 @@ func main():
= 5
do:
>> value := if var := NONE:Int:
>> value := if var := none:Int:
var
else:
0
@ -310,7 +312,7 @@ func main():
>> opt
do:
>> opt := NONE:Int
>> opt := none:Int
>> if opt:
>> opt
else:
@ -319,7 +321,7 @@ func main():
>> not 5?
= no
>> not NONE:Int
>> not none:Int
= yes
>> [Struct(5,"A")?, Struct(6,"B"), Struct(7,"C")]

View File

@ -36,9 +36,9 @@ func main():
fail("Couldn't read lines in $tmpfile")
>> (./does-not-exist.xxx):read()
= NONE : Text?
= none : Text?
>> (./does-not-exist.xxx):read_bytes()
= NONE : [Byte]?
= none : [Byte]?
if lines := (./does-not-exist.xxx):by_line():
fail("I could read lines in a nonexistent file")
else:

View File

@ -5,7 +5,7 @@ func main():
= 60 : Int?
>> (+: [:Int])
= NONE : Int?
= none : Int?
>> (+: [10, 20, 30]) or 0
= 60
@ -37,7 +37,7 @@ func main():
= yes
>> (<=: [:Int])
= NONE : Bool?
= none : Bool?
>> (<=: [5, 4, 3, 2, 1])!
= no

View File

@ -1,5 +1,5 @@
struct Foo(name:Text, next=NONE:@Foo)
struct Foo(name:Text, next=none:@Foo)
enum MyEnum(Zero, One(x:Int), Two(x:Num, y:Text))
@ -88,7 +88,7 @@ func main():
= yes
do:
>> obj := NONE:Num
>> obj := none:Num
>> bytes := obj:serialized()
>> deserialize(bytes -> Num?) == obj
= yes

View File

@ -2,11 +2,11 @@
struct Single(x:Int)
struct Pair(x,y:Int)
struct Mixed(x:Int, text:Text)
struct LinkedList(x:Int, next=NONE:@LinkedList)
struct LinkedList(x:Int, next=none:@LinkedList)
struct Password(text:Text; secret)
struct CorecursiveA(other:@CorecursiveB?)
struct CorecursiveB(other=NONE:@CorecursiveA)
struct CorecursiveB(other=none:@CorecursiveA)
func test_literals():
>> Single(123)

View File

@ -7,7 +7,7 @@ func main():
>> t["two"]
= 2 : Int?
>> t["???"]
= NONE : Int?
= none : Int?
>> t["one"]!
= 1
>> t["???"] or -1
@ -22,7 +22,7 @@ func main():
>> t.length
= 2
>> t.fallback
= NONE : {Text:Int}?
= none : {Text:Int}?
>> t.keys
= ["one", "two"]
@ -37,7 +37,7 @@ func main():
>> t2["three"]
= 3 : Int?
>> t2["???"]
= NONE : Int?
= none : Int?
>> t2.length
= 1

View File

@ -35,7 +35,7 @@ func main():
>> Text.from_bytes([:Byte 0x41, 0x6D, 0xC3, 0xA9, 0x6C, 0x69, 0x65])!
= "Amélie"
>> Text.from_bytes([Byte(0xFF)])
= NONE : Text?
= none : Text?
>> amelie2 := "Am$(\U65\U301)lie"
>> amelie2:split()
@ -189,9 +189,9 @@ func main():
!! Test text:find()
>> " one two three ":find($/{id}/, start=-999)
= NONE : Match?
= none : Match?
>> " one two three ":find($/{id}/, start=999)
= NONE : Match?
= none : Match?
>> " one two three ":find($/{id}/)
= Match(text="one", index=2, captures=["one"]) : Match?
>> " one two three ":find($/{id}/, start=5)
@ -222,7 +222,7 @@ func main():
= ["PENGUIN"]
>> Text.from_codepoint_names(["not a valid name here buddy"])
= NONE : Text?
= none : Text?
>> "one two; three four":find_all($/; {..}/)
= [Match(text="; three four", index=8, captures=["three four"])]
@ -249,11 +249,11 @@ func main():
>> "Hello":matches($/{id}/)
= ["Hello"] : [Text]?
>> "Hello":matches($/{lower}/)
= NONE : [Text]?
= none : [Text]?
>> "Hello":matches($/{upper}/)
= NONE : [Text]?
= none : [Text]?
>> "Hello...":matches($/{id}/)
= NONE : [Text]?
= none : [Text]?
if matches := "hello world":matches($/{id} {id}/):
>> matches

View File

@ -520,7 +520,7 @@ type_t *get_type(env_t *env, ast_t *ast)
return Type(OptionalType, .type=NULL);
type_t *t = parse_type_ast(env, Match(ast, None)->type);
if (t->tag == OptionalType)
code_err(ast, "Nested optional types are not supported. This should be: `NONE:%T`", Match(t, OptionalType)->type);
code_err(ast, "Nested optional types are not supported. This should be: `none:%T`", Match(t, OptionalType)->type);
return Type(OptionalType, .type=t);
}
case Bool: {