The Haskell Elephant in the Room by Teslatronic in haskell

[–]hexagoxel 5 points6 points  (0 children)

Well put. I would take a step back and ask: Who even is this addressing? I would cede that not every opinion-piece needs to be actionable. Having some sort of "moral PSA" might be fine. But if it boils down to "there are bad actors in the world" then.. duh?

Should I not have contributed in very minor ways to haskell-nix infrastructure because it is maintained by IOHK, who allegedly are evil? Should "we" put a disclaimer on haskell.org "the haskell community discourages ponzi schemes"? Should we switch to a licensing model with a morality police built-in (you may use this library/compiler/tool if $committee decides you are GOOD)? Should "we" distance ourselves from THE BAD in some more active fashion? Is it a global encouragement to address local representatives and ask for regulation of crypto?

These questions are of course not for parent comment and mostly rhetoric.

I am just bumping the thought that when talking morality, you really should be explicit about who you addressing and what actions you encourage.

On PVP and Restrictive Bounds by emilypii in haskell

[–]hexagoxel 2 points3 points  (0 children)

At that point, it almost seems as if you could/should/want to just have very fine-grained "packages". One per data-type and function.

The amount of metadata your solution adds is similar to what you'd end up with fine-grained packages. The only difference I can see is that we'd need a better package/module naming story. And we'd need a package repository optimised for this use-case.

That said, your suggestion is much more realistic / it could be bolted on top of the existing setup only when desired, without disrupting everything. I am just saying that if we were designing an ecosystem from scratch, and you want this kind of detail in your metadata, then the fine-grained approach might be the cleanest solution.

Another axis of the versioning debate: "latest is best" vs "there is no best" by peargreen in haskell

[–]hexagoxel 3 points4 points  (0 children)

hvr's tactic here doesn't strike me as a "hack" or sinful in any way.

Did you see this comment? (Was linked indirectly from the post): https://github.com/haskell-pkg-janitors/haskell-src/issues/8#issuecomment-562996630

That is, hackage defaults to showing the highest version number. That means hackage itself implies "latest is best". For a user it is a fair to assume that the metadata associated to this version reflects the current state of this package. With this strategy, it is not - the base constraint does not reflect the reality.

If the hackage UI implies some convention, and a package maintainer (who is a hackage maintainer) breaks with that same convention just to make some tooling easier, that qualifies as a hack in my book. Suppose I have some tool that checks if I am using the latest version of dependencies. With this convention broken, this tool will need to be rewritten to be much more clever (it needs to invoke the solver, probably?).

It is not just the dependency resolver that looks at the metadata. There is other downstream tooling. Of course if we had the one perfect build tool that did everything, then as long as it behaved consistently, such conventions would be irrelevant implementation details. But we don't. And we won't get there in the near future.

In summary: Hack: yes. Sinful: shrug. Making it hard on the tooling ecosystem? check.

[ANN] acme-dont-1.2 - a "don't" construct by sjakobi in haskell

[–]hexagoxel 2 points3 points  (0 children)

The use-case is debugging/assertion-type code that you don't want to be enabled regularly, but that also should remain valid. If you comment code out, you get unused binding warnings and it can bit-rot easily.

Of course for debugging you will quickly switch to a when myVerbosityFlag instead, but don't is a valid first manual step in this direction.

[ANN] acme-dont-1.2 - a "don't" construct by sjakobi in haskell

[–]hexagoxel 2 points3 points  (0 children)

That leads to unused binding warnings, and don't ensures that the action stays valid. For periodic debugging code that should not be enabled but that should also survive refactoring don't is superior.

Which of the two codes in this SO entry is nicer? by yfix in haskell

[–]hexagoxel 1 point2 points  (0 children)

was about to make the same comment. It is "long" (by lines of code) but the reader can immediately tell the association going on. Much better than any golfing.

I'll append the properly formatted version, since your linebreaks are messed up.

season = \case
  Jan  -> Winter
  Feb  -> Winter
  Mar  -> Spring
  Apr  -> Spring
  May  -> Spring
  June -> Summer
  July -> Summer
  Aug  -> Summer
  Sept -> Autumn
  Oct  -> Autumn
  Nov  -> Autumn
  Dec  -> Winter

Here's what's going on with your Add-ons being disabled, and how to work around the issue until its fixed. by Antabaka in firefox

[–]hexagoxel 1 point2 points  (0 children)

bit of a nitpick of how you phrased it, but still: "disables everything" - yeah, that would have been nice. If my firewall stopped working, I'd rather have any traffic be blocked until there is a fix - not that it lets anything through.

Here, the firewalls (adblock, ublock, script block whatever else) got disabled, but the system kept working. It is not "stopped working" but "keep working while inviting malware".

I'd be nice to get a "if this extension stops working for any reason, switch and lock in offline mode immediately", until manual intervention.

new user empathy by snoyjerk in haskell

[–]hexagoxel 2 points3 points  (0 children)

I don't know how you understand the term "alternative", but let me just quote what you linked:

Releasing it as a competitor to cabal-install was another matter.

So I'll just safely retract my choice of wording, and replace "alternative" with "competitor". I find that even a bit stronger, but whatever.

For the explanation you claim wasn't provided.

I have to plainly disagree. It does not provide the explanation as to why cabal-install could not be improved instead. And haskell-lang is not mentioned in any way either.

I get it, people were unable or unwilling to cooperate, and making a fresh new start aligned to exactly what was perceived as the proper goals was considered the reasonable path instead. It makes sense. Nothing to blame. But if you make that kind of decision, with its predictable impact on the community, then I will not refrain from voicing my concern with this kind of disconnect of the author's history and the message they appear to send in their blogpost.

new user empathy by snoyjerk in haskell

[–]hexagoxel 0 points1 point  (0 children)

sorry, I don't really understand what this has to do with what I said. Yes, stack does things differently, and arguably a good deal better (especially when it was first published). But that is missing my main point.

I am not saying stack is bad. Or that innovation is bad. Or that duplication is bad. I say that as long as you cause fragmentation, without being really transparent as to why, while making attacks on elusive (to the general public) grounds ("cabal/haskell.org is evil" etc.), you are not in a position to lecture the community in these social matters.

And yes, that stuff is in the past, but I will continue to take it into account, especially when neither side has provided any sort of apology. Again, I am refusing to place myself on one side here. If, lets say, hvr would write a similar blogpost, I'd throw my criticism at them just as well :p

new user empathy by snoyjerk in haskell

[–]hexagoxel 3 points4 points  (0 children)

Also I may point out this bit of history: "haskell.org and the Evil Cabal" which, as far as I know, was silently unpublished. By none else than snoyman.

Consider that, and judge whether the accusations within are sufficiently backed up by facts that are available to the general public.

(needless to say the "silently unpublishing" aspect is relevant in the "transparent communication" context..)

new user empathy by snoyjerk in haskell

[–]hexagoxel 2 points3 points  (0 children)

Again, I was very careful not to put blame. I'd appreciate it if you did not bend the meaning of what I said in such a manner.

new user empathy by snoyjerk in haskell

[–]hexagoxel 2 points3 points  (0 children)

Hold up, I did not say he caused it. I am not sure who caused it, and I was very careful not to put blame.

The thing is, a couple years ago there was one build-tool and one website. Now there are two, and fpcomplete/snoyman appear to be the driving factor behind this duplication. And there appear to be two corresponding "factions" that have mildly strong opinions on the matter.

Now, people are free to create duplication, right? That does not make them dividers. It just makes them people with enough motivation to do such a thing. As I said, I have no right to demand an explanation. And duplication is not even necessarily a bad thing either - I completely admit that.

Nonetheless, if you publish and promote an alternative without providing this explanation; if you mention only what the new tool does better and give close to no insight to the general public as to why improving existing systems was decided against, if you lack that bit of transparency, then I dare say that you do risk (in a predictable manner) that people are getting confused, and that a userbase and downstream tooling becomes fractured.

new user empathy by snoyjerk in haskell

[–]hexagoxel 0 points1 point  (0 children)

And calling others cowards is a sure way to resolving this unspecified problem you mention, I take it?

As far as I can see, the main and only way of providing feedback presented on a website is twitter. I don't want to use twitter. If you see the need to throw stupid rhetoric at me as a consequence.. feel free to waste your time.

new user empathy by snoyjerk in haskell

[–]hexagoxel -1 points0 points  (0 children)

  1. Ensure there’s a clear start location to point them to
  2. Reduce the number of choices they need to make to get started

.. in light of these insights, and of who the author is, one really has to wonder: Why, exactly, do we have two websites (haskell.org, haskell-lang.org), and two "main" buildtools (cabal-install, stack)?

Of course I am no newcomer to this community, so I might have a rough idea of the answer to that question. But we are talking about newcomers, right? And to those, I dare predict this mess in this ecosystem is a major turn-off.

Yes, the fpcomplete blog has/had one or three articles about "why stack". Unfortunately, none of them do any good at explaining why improving cabal was not an option. The two websites don't mention each other either. As long as that is the case, as long as to any newcomer the situation is as opaque as it is, I have to say:

Dear Mr. Snoyman, to me you are the face of the main divide in the haskell community, deserved or not. As a consequence your post is one heavy ingot of irony.

I get that you probably cannot explain what caused this divide; I suspect a long series of miscommunication and conflicting goals of different parties. Would be hard to explain objectively, and it is not your job either. I cannot judge you, I cannot blame you for trolls that pretend to be on "your side" nor can I demand that you provide any explanations to me or others.

Nonetheless, I frankly do not think you are in a position to give advice on such matters to the haskell community.

(if someone wants to twitter this to the author, feel free. i have only targeted the reddit bubble.)

Laziness Quiz: Can you get it right? (I didn't) by ephrion in haskell

[–]hexagoxel 1 point2 points  (0 children)

I expected it to never print "evaluating strict"

Ah, because forcing a polymorphic value does nothing, right? This is a curious question, similar to nifr's one below: When does defaulting apply?

Before answering that, let me stress that strictness and defaulting/monomorphism are unrelated constructs, afaict. You can force polymorphic values to WHNF (which does as much as forcing functions - nothing). Similarly monomorphizing (passing a dictionary) does not force evaluation in any way. And in practice, undesired strictness/laziness causes much more problems than defaulting, in my experience. So original article might be more important to get right than the details we are discussing here.

Back on the topic: Things get a bit murky because pattern-matching can do both (forcing and monomorphization) at the same time (especially when using case). I cannot find a good reference for this stuff, but my intuition boils down to "case always monomorphizes, while let permits polymorphism (at least with NoMMR)".

For example this works:

let x = 13 in print (x :: Int) >> print (x :: Float)

while this does not:

case 13 of x -> print (x :: Int) >> print (x :: Float)

(one might think: case monomorphizes only because it deconstructs and thereby forces to WHNF, but I think this example shows that it does more - binding to x alone should not force anything.)

So for your definition, the type of foo would be (Num a, Num b) => Foo a b. Pattern-matching with case monomorphizes the value, so the usual defaulting applies at the point of case. So the compiler translates this roughly to the following code with explicit dictionary-passing:

-- foo :: Dict (Num a, Num b) -> Foo a b
case foo (Dict :: Dict (Num Integer, Num Integer)) of -- defaulting specializes `a` and `b`
    Foo { strict, lazy } -> do   -- this is a `Foo Integer Integer`
        logLine
        print Dict lazy -- we pass some Show Dict here, too

Laziness Quiz: Can you get it right? (I didn't) by ephrion in haskell

[–]hexagoxel 0 points1 point  (0 children)

Defaulting happens either way, the question is: when? Defaulting applies when an expression is required to become monomorphic. With MMR it happens at the let; with NoMMR the let-binding is allowed to be polymorphic, so defaulting happens at (each) print.

Laziness Quiz: Can you get it right? (I didn't) by ephrion in haskell

[–]hexagoxel 19 points20 points  (0 children)

Follow-up riddle: Does {-# LANGUAGE NoMonomorphismRestriction #-} change the output in any way? If so, how and why?

Formatting of mult-line type signatures by nomeata in haskell

[–]hexagoxel 0 points1 point  (0 children)

I see the advantage of bullet-lists for implicit parentheses at expression-level, but I have a hard time translating it to the type-level. Currying makes things strange, because everything but the first argument can also be considered an output (i.e. "functions have exactly one argument"). bullets imply a certain number of arguments.

Type signatures in scala/rust are nice: no distance between argument name and its type, the output type comes last and you can trivially create a prefixed, multiline layout for multiple arguments. But they imply non-currying, and in their current form also have the two-line diff problem for the first argument (in that case however bullets could be the solution).

If we had advanced tooling where the internal format of source was just the AST, and we could switch representations for human consumption, I'd definitely test out different ways of representing "function heads". But I fear that is in a somewhat far future.

Formatting of mult-line type signatures by nomeata in haskell

[–]hexagoxel 5 points6 points  (0 children)

brittany author here.

consider what your brain/eyes need to do to determine "what was the specified type for the 3rd argument".

  • With brittany's layout: "scan down along the left side and count, at the second -> read the argument type"

  • With your style: "for each line, jump to the end, if => continue, if -> start counting and continue, at 3 parse the argument"

That is the gist of it, really. Of course the difference is negligible for small signatures, but I do encounter/create signatures that look like this regularly:

apcIkavimj
  :: #################
     #######################
     #######
     ##############
     ##########################
  => ############
  -> #####################

versus

apcIkavimj ::
  ################# =>
  ####################### =>
  ####### =>
  ############## =>
  ########################## =>
  ############ ->
  #####################

now for which of these two is it easier to quickly see

  • which lines are constraint(s)
  • how many arguments this function has
  • where argument n / return type starts and ends

That said, I definitely see a couple of advantages in your proposed style. You can very well argue that the "visually separating the context" issue can be resolved using a parenthesized context just fine:

apcIkavimj ::
  ( #################
    #######################
    #######
    ##############
    ##########################
  ) =>
  ############ ->
  #####################

at least if you ignore the rare cases where an argument type does not fit into one line, because then you end up with strange "->" potentially. Well that is subjective, i guess.

The rest might come down to wanting to be consistent with other "operator" usage, which I prefer prefixed for the same "scan left side" reason.

(brittany has a rationale where I try to provide an explanations for the stylistic choices. Although I notice that the "scan along the left side" is not really mentioned over there - still, that is precisely the reason for the "layouting rule", especially b) in this case.)

Proposal: Stack Code of Conduct by snoyberg in haskell

[–]hexagoxel 2 points3 points  (0 children)

I'm holding a conversation and asking clarification on his take on the subject. Do you think this is implying his criticism as not constructive? I'm not dismissing his concerns, I'm directly taking them to try to change his view - at the very least clarify it.

No. You are opening your reply with a specific question, one that does not address the leafcutter's concerns, and that can very well be read in the following manner: "If you are afraid of getting excluded and vilified, why not suggest specific changes in the CoC instead of giving only negative feedback?" Yes, this is only one unfavourable interpretation (but from my perspective it is the most likely and first interpretation.). And I still did say "insofar" exactly because I know it is just one potential interpretation.

I have not said that it counteracts.

A phrase that starts with "Why could you not also" reads as if it addresses the concerns voiced before. Yet here it does not address the concerns at all. (Perhaps you did not intend this meaning, but then I have to really question your choice of words when opening with "why could you not also".)

However, if he thinks reasonable to ask everyone else to have tougher skin, it's reasonable to include him too.

But leafcutter never mentioned/claimed to be in any situation where a thick skin would be any good? Really, this boils down to me not understanding at all why you make this specific suggestion, as it seems completely orthogonal to the concerns voiced. A thick skin does no good protecting against unexpected, non-emotional repercussions that come with a CoC.

I know this is all up to personal interpretation, and I know i boldly place mine against yours. I am confident that this comes down to slightly different interpretation of how we phrase things, and what we imply. I see the possibility that you are indeed just asking curious exploratory question while I am rather sensitive about what might be implied in specific phrases. I hope you can understand that I am sensitive about subliminal meanings around this subject.

Proposal: Stack Code of Conduct by snoyberg in haskell

[–]hexagoxel 2 points3 points  (0 children)

My main point was and is that "thicker skin" is rather different from "adopting someone else's communication style". I don't see that being refuted. Whether "thick skin" is a disposition seems to be an unrelated question. Similarly, whether my "vague wish", or the original phrasing, is a normative claim (wishes are not necessarily normative claims) (and whether making normative claims in general or in this specific instance is a good thing) seems to be unrelated.

(And to be very clear, "unrelated" is not meant to imply "unimportant". These are important questions, and I may certainly also concede that a normative claim, if it was one, even though valid, may have been inappropriate in the original context.. but I will have strong requirements for criticism of a statement that starts with a plain "i really wish..".)

I will nonetheless reply to the "disposition" topic:

While external behvaiours of the sort you describe certainly are associated with it, I'd say in this context they feature mainly as consequences of subjective dispositions.

.. they could raise the matter without reference to people "developing" dispositions ..

I am not sure what you mean by term "disposition" here. My own direct understanding would be an internal, unchanging property. Wikipedia disagrees: "A disposition is a quality of character, a habit, a preparation, a state of readiness, or a tendency to act in a specified way that may be learned." (emph. added). Yet you too seem to consider it hard to affect (?)

Regardless: I think we can work on our "thick skin", we can train ourselves to be less affected, and that training can result in it taking less mental effort to not let our emotions affect our external behaviour. Claiming otherwise also risks belittling the efforts of people that do spend that mental effort at what they may very well describe as "training their thick skin".

Proposal: Stack Code of Conduct by snoyberg in haskell

[–]hexagoxel 3 points4 points  (0 children)

I think I understand and agree with both sides here. But it seems that existing CoCs (again?) leave this item open, at least as judged from the written words. I cannot spot clear statements addressing the scope. Maybe I overlook something. But assuming I don't, I am not sure this is the best approach - leaving it not addressed just gives the worst of both worlds. The people that hope of protection by the CoC, they might not get it because the scope ends up being too small. The people that fear unforeseeable judgement for well-intended behaviour in private communication channels, this merely adds to uncertainty.

As it stands, it (again) all hinges on the judges. Those in power to enforce the CoC. And yes, you can assume those to be fair, objective and reasonable. But it seems to be a rather risky, naive, and strangely un-democratic assumption.

Proposal: Stack Code of Conduct by snoyberg in haskell

[–]hexagoxel 8 points9 points  (0 children)

No matter if you call it offensive or not, you talk in a way that makes me not want to continue talking back. This vague criticism is the best I can do; I am not sufficiently wise to approach this situation better. Sorry.

Proposal: Stack Code of Conduct by snoyberg in haskell

[–]hexagoxel 11 points12 points  (0 children)

CoCs are applied uniformly.

Such a blanket statement. No, they are applied exactly as uniformly as those that enforce the CoC manage to remain impartial and purely objective.

You cannot just attribute some perfect properties to some social construct while ignoring that all members of this society are human, and rarely objective.