savi-lang / savi

A fast language for programmers who are passionate about their craft.
BSD 3-Clause "New" or "Revised" License
155 stars 12 forks source link

Add "leading dot" syntax, enabled by type inference #274

Open jemc opened 2 years ago

jemc commented 2 years ago

Swift has this nifty feature they call Implicit Member Expression, which is often used for enums, but can also be used for static functions/variables.

In Savi we could use a similar feature for enums, static functions (fun non) and constructors (new).

The basic idea is that if the expression .baz can be used as shorthand for Foo.Bar.baz in a place where the type inference system knows that the type Foo.Bar is expected.


Here are some examples of places in real Savi code that could be made more succinct:

--- a/src/HTTPServer.RequestReader.savi
+++ b/src/HTTPServer.RequestReader.savi
@@ -107,7 +107,7 @@
           try (
             @_request.content_length = stream.token_as_positive_integer!.usize
           |
-            @_error = HTTPServer.Request.Error.InvalidContentLength
+            @_error = .InvalidContentLength
             error!
           )
         | @_next_header === "transfer-encoding" | 
diff --git a/src/Map.savi b/src/Map.savi
index c32555b..7e19a40 100644
--- a/src/Map.savi
+++ b/src/Map.savi
@@ -14,7 +14,7 @@
     @_init_array(((prealloc * 4) / 3).max(8).next_pow2)

   :fun ref _init_array(space USize)
-    @_array = Array((Pair(K, V) | _MapEmpty | _MapDeleted)).new(space)
+    @_array = .new(space)
     space.times -> (@_array << _MapEmpty)

   :fun ref _resize(space USize)
jemc commented 2 years ago

Note that one downside of this is that if the type inferred for the expression becomes more general (like if it goes from Foo.Bar to (Foo.Bar | None)), then this kind of shorthand syntax becomes untenable. This means that what appears to be a non-breaking change (an API that accepts a broader range of values at its input) can actually break compilation for call sites using the shorthand syntax (it will no longer have a single type to refer to as its antecedent).

However, this is not a unique disadvantage that would be introduced by this feature - it is already present in other type inference related features, like array inference that can infer the type of array to instantiate based on the antecedent type, but fails to do so when there is more than one array-like option in the antecedent types.

jemc commented 2 years ago

Marking this as blocked by the type system rewrite in #76.