TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Moving Beyond Type Systems

77 pointsby flexagoonabout 1 year ago

8 comments

sparkieabout 1 year ago
&gt; 4. External resources (files, I&#x2F;O): this would be a very difficult topic if not for our simple question. Only writing to a file or outputting to an I&#x2F;O stream is considered an effect, as only the process of writing mutates external state. Reading data creates new state, but does not modify it, therefore reading data of various sorts is not an effect. Because of this, printing is effectful, but reading from stdin is not.<p>Lost me at this part. Of course reading is a side-effect. A function which reads from a file&#x2F;console cannot be <i>pure</i>. Purity implies referential transparency - a function given the same arguments will always return the same result.<p>If we consider the example given:<p><pre><code> pub fn read_guess() -&gt; int { return io.read_int(&quot;Take a guess (0-100): &quot;); } </code></pre> We should take `read_int` to be effectful because it will have the effect of advancing the position to read from in the console&#x27;s buffer. If it didn&#x27;t, it would always read from the same position, so even if the user took a second guess, the first guess would be read again the second time `read_int` is called. So given that `read_int` is effectful, so too is `read_guess`.<p>&gt; 1. Well, creating a variable is creating new state, but it’s not changing the state, therefore creating a variable is not an effect, but changing it is.<p>Creating a local variable isn&#x27;t a side-effect, but <i>allocating</i> a variable is a side effect. Sure enough, if we also free the allocation before leaving scope, we can avoid propagating that effect, but if you return a value that contains anything allocated by a function, then the function becomes effectful.
评论 #40542442 未加载
评论 #40543634 未加载
评论 #40542728 未加载
rebeccaskinnerabout 1 year ago
I&#x27;ve been thinking a lot about effects systems recently. A few months ago I implemented an effects system based interpreter in Haskell for an embedded DSL prototype for a project at work. In our case, the effects we were concerned with were all some variation of reading data, and the effects based approach allowed us to statically ensure that data would be available, and let us perform some clever optimizations to reduce the overhead of large IO operations.<p>We&#x27;ve since rewritten the system and, while we still support an optional effects based style in our DSL, it&#x27;s not being used very heavily. In practice, our user found the ergonomics of the effects system quite challenging, and it introduced some type inference challenges. The biggest problem was that our use-cases ended up with functions that would have hundreds of effects, and it was fairly unwieldy and the type errors were difficult to deal with. Since we&#x27;ve introduced the updated version, most users prefer to user our newer features that allow them to write more traditional code even though it means they don&#x27;t get composable effects.<p>On the other side of the experience, I&#x27;ve come to believe that effects systems are a good idea, but when adding them to an existing language it&#x27;s probably best to make them an opt-in feature that can be used to constrain specific small parts of a program, rather than something that should be applied globally. I also think we need a bit more research into the ergonomics before they are going to appeal to a lot of users. That said, the guarantees and optimization opportunities ours gave us were really nice, and were quite difficult to achieve without building on top of the effects system (our new system is about an order of magnitude more code, for example).
评论 #40543384 未加载
评论 #40542908 未加载
评论 #40542672 未加载
评论 #40542895 未加载
turnsoutabout 1 year ago
What is the actual problem that this effect-oriented approach addresses? The effects of methods that are called by other methods will be concealed, so at the calling site, you&#x27;ll have no idea that the high-level API `do_stuff` is going to utilize `io`. That is, unless the effect decoration &quot;infects&quot; the caller like `async`, in which case every complex API method will be decorated with a huge number of effects.<p>Simply put, what does this buy us?
评论 #40542320 未加载
评论 #40543446 未加载
评论 #40542580 未加载
评论 #40542322 未加载
评论 #40542493 未加载
评论 #40543678 未加载
评论 #40546010 未加载
taericabout 1 year ago
I can&#x27;t but feel this is running head first into statements versus expressions.<p>Specifically the part that views effects as growing in size and that being contrary to desired behavior. Strikes me as worrying about similar concerns.<p>Seems more that it is the eager evaluation of each line of code that is a problem. Nothing wrong with growing the footprint of concern on code. The problem is how to annotate the concern.<p>Consider, adding &#x27;logger.whatever(...)&#x27; is likely not a concern to the program. Being able to annotate the logger as not an effect to check makes sense. Of course, all edge cases matter. Are the arguments eagerly evaluated? What if the logger doesn&#x27;t even use them, due to level?<p>With lisp, the magic wasn&#x27;t only that you can treat code as data, but also that you could define code that ran at different times. And you could largely do that in &quot;user space.&quot;
al2o3crabout 1 year ago
The article starts off with a motivating example of effects getting &quot;bigger&quot; when composed but I don&#x27;t see where it does anything to contain &#x2F; control that expansion (other than &quot;proto&quot; which does full inference)<p>Seems like complex functions could end up with effects lists of unwieldy size, similar to how Elm programs end up with a giant &quot;Msg&quot; type.
评论 #40542582 未加载
评论 #40542643 未加载
评论 #40543048 未加载
librasteveabout 1 year ago
in the OP example, this is considered bad<p><pre><code> let x: string = &quot;hello world&quot;; x = 32; #type error </code></pre> however, a well designed <i>strong</i> typesystem should be able to compose types to allow this if desired by the coder (eg. to read in a column of numbers from a csv)<p><pre><code> my $forty-two = 42 but &#x27;forty two&#x27;; say $forty-two+33; # OUTPUT: «75␤» say $forty-two.^name; # OUTPUT: «Int+{&lt;anon|1&gt;}␤» say $forty-two.Str; # OUTPUT: «forty two␤» </code></pre> Calling ^name shows that the variable is an Int with an anonymous object mixed in. However, that object is of type Str, so the variable, through the mixin, is endowed with a method with that name, which is what we use in the last sentence.<p><a href="https:&#x2F;&#x2F;docs.raku.org&#x2F;routine&#x2F;but" rel="nofollow">https:&#x2F;&#x2F;docs.raku.org&#x2F;routine&#x2F;but</a>
评论 #40546029 未加载
User23about 1 year ago
Out of curiosity is there any point to a loop that doesn’t produce some effect in its body? Obviously I mean traditional imperative looping constructs and not map functions that return a value.
评论 #40542860 未加载
评论 #40542654 未加载
name_nick_sex_mabout 1 year ago
This post needs to justify itself with a solid real example of how this <i>additional effect</i> system provides value