TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Moving Beyond Type Systems

77 点作者 flexagoon12 个月前

8 条评论

sparkie12 个月前
&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 未加载
rebeccaskinner12 个月前
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 未加载
turnsout12 个月前
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 未加载
taeric12 个月前
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;
al2o3cr12 个月前
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 未加载
librasteve12 个月前
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 未加载
User2312 个月前
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_m12 个月前
This post needs to justify itself with a solid real example of how this <i>additional effect</i> system provides value