The functionality is fairly simple yet: there is a file browser on the left, and the editor (I'm using the ACE web editor) on the right. There is no save button, any change is automatically saved to disk (you use source version control, right?). On the server, there is a GHCi session for each cabal component in your project, and any change causes a reload, and you can see the errors/warnings in a menu and in the editor's annotations. You can build, run tests and benchmarks, and I've just added ":info" support. The fact that we're using GHCi makes it fast, but I'm sure there's loads of wrinkles to iron out still.
Anyway, if you're interested in a test ride, just clone from Github and get going!
We are happy to announceMuniHac
This Hackathon is intended for everyone who is interested to write programs in Haskell, whether beginner or expert, whether hobbyist or professional.
In the tradition of other Haskell Hackathons such as ZuriHac, HacBerlin, UHac and many more, the plan is to bring together up to a hundred of Haskell enthusiasts to work together on any Haskell-related projects they like, to share experiences, and to learn new things.
Attendance is free of charge, but there is a limited capacity, so you must register!
We are going to set up a mentor program and special events for Haskell newcomers. So if you are a Haskell beginner, you are very much welcome! And if you’re an expert, we’d appreciate if you’d be willing to spend some of your time during the Hackathon mentoring newcomers. We will ask you about this during the registration process.
We’re also planning to have a number of keynote talks at the Hackathon. We’re going to announce these soon.
We hope to see you in Munich!
- June 13th, 2016:
You want this list: [1, -1, 1, -1, ...]
How would you produce this value in #Haskell ?
- Wai Lee Chin Feman @wchinfeman
(set plop to be identity, and set transformstate to be (*) -1)
- Philipp Maier @AkiiZedd `iterate negate 1’
- Patrick Mylund @pmylund concat $ repeat [1, (-1)]
- Gary Fixler @gfixler No need for the parens in a list.
- Jeff Foster @fffej and Kevin Meredith @Gentmen
iterate (* (- 1)) 1
- Spencer Janssen @spencerjanssen and Андреев Кирилл @nonaem00
cycle [1, -1]
- Philipp Maier @AkiiZedd:
I’m curious: Since concat is O(n) wouldn’t it take more and more time depending on how many items you take?
- Patrick Mylund @pmylund Looks like they compile to the same thing https://gist.github.com/patrickmn/9a92ab2a088018b2c0631f3bcfd60ebe
- Philipp Maier @AkiiZedd I’m actually surprised the compiler can optimise this away :o Thanks for showing me ddump-simpl!
- Eyal Lotem @EyalL concat is foldr (++), not foldl. O(1) work is done to produce the next item. [1,-1]++([1,-1]++(...
- Philipp Maier @AkiiZedd:
- Wai Lee Chin Feman @wchinfeman
- David Turner @DaveCTurner I'd actually write 'cycle [1,-1]' but I like the elegant, alliterative obscurity of 'iterate negate 1'
- Fatih Karakurt @karakfa alt=1:[-x|x<-alt]
[ Danielle Sucher reminded me of this article I wrote in 1998, before I had a blog, and I thought I'd repatriate it here. It should be interesting as a historical artifact, if nothing else. Thanks Danielle! ]
I avoided syntax coloring for years, because it seemed like a pretty stupid idea, and when I tried it, I didn't see any benefit. But recently I gave it another try, with Ilya Zakharevich's `cperl-mode' for Emacs. I discovered that I liked it a lot, but for surprising reasons that I wasn't expecting.
I'm not trying to start an argument about whether syntax coloring is good or bad. I've heard those arguments already and they bore me to death. Also, I agree with most of the arguments about why syntax coloring is a bad idea. So I'm not trying to argue one way or the other; I'm just relating my experiences with syntax coloring. I used to be someone who didn't like it, but I changed my mind.
When people argue about whether syntax coloring is a good idea or not, they tend to pull out the same old arguments and dust them off. The reasons I found for using syntax coloring were new to me; I'd never seen anyone mention them before. So I thought maybe I'd post them here.
Syntax coloring is when the editor understands something about the syntax of your program and displays different language constructs in different fonts. For example, cperl-mode displays strings in reddish brown, comments in a sort of brick color, declared variables (in my) in gold, builtin function names (defined) in green, subroutine names in blue, labels in teal, and keywords (like my and foreach) in purple.
The first thing that I noticed about this was that it was easier to recognize what part of my program I was looking at, because each screenful of the program had its own color signature. I found that I was having an easier time remembering where I was or finding that parts I was looking for when I scrolled around in the file. I wasn't doing this consciously; I couldn't describe the color scheme any particular part of the program was, but having red, gold, and purple blotches all over made it easier to tell parts of the program apart.
The other surprise I got was that I was having more fun programming. I felt better about my programs, and at the end of the day, I felt better about the work I had done, just because I'd spent the day looking at a scoop of rainbow sherbet instead of black and white. It was just more cheerful to work with varicolored text than monochrome text. The reason I had never noticed this before was that the other coloring editors I used had ugly, drab color schemes. Ilya's scheme won here by using many different hues.
I haven't found many of the other benefits that people say they get from syntax coloring. For example, I can tell at a glance whether or not I failed to close a string properly—unless the editor has screwed up the syntax coloring, which it does often enough to ruin the benefit for me. And the coloring also slows down the editor. But the two benefits I've described more than outweigh the drawbacks for me. Syntax coloring isn't a huge win, but it's definitely a win.
If there's a lesson to learn from this, I guess it's that it can be valuable to revisit tools that you rejected, to see if you've changed your mind. Nothing anyone said about it was persuasive to me, but when I tried it I found that there were reasons to do it that nobody had mentioned. Of course, these reasons might not be compelling for anyone else.Addenda 2016
Looking back on this from a distance of 18 years, I am struck by the following thoughts:
Syntax higlighting used to make the editor really slow. You had to make a real commitment to using it or not. I had forgotten about that. Another victory for Moore’s law!
Programmers used to argue about it. Apparently programmers will argue about anything, no matter how ridiculous. Well okay, this is not a new observation. Anyway, this argument is now finished. Whether people use it or not, they no longer find the need to argue about it. This is a nice example that sometimes these ridiculous arguments eventually go away.
I don't remember why I said that syntax highlighting “seemed like a pretty stupid idea”, but I suspect that I was thinking that the wrong things get highlighted. Highlighters usually highlight the language keywords, because they're easy to recognize. But this is like highlighting all the generic filler words in a natural language text. The words you want to see are exactly the opposite of what is typically highlighted.
Syntax highlighters should be highlighting the semantic content like expression boundaries, implied parentheses, boolean subexpressions, interpolated variables and other non-apparent semantic features. I think there is probably a lot of interesting work to be done here. Often you hear programmers say things like “Oh, I didn't see the that the trailing comma was actually a period.” That, in my opinion, is the kind of thing the syntax highlighter should call out. How often have you heard someone say “Oh, I didn't see that while there”?
I have been misspelling “arguments” as “argmuents” for at least 18 years.
Looking back at this, what bugs me most is the late addition of sets, which were only added after a user requested it. Why didn't his come up right at the start? “interval-containers” would have been a better and more general package name.
The really big change - supporting user-defined intervals via a type class - was caused by my initial distrust of nonstandard language extensions. The result of this is one more level in the module structure for the now-preferred generic version, e.g.:import qualified Data.IntervalMap.Generic.Strict as IVM
What it still unclear is where to put the Interval type class. There are many useful interval data structures and using Data.Interval for this particular purpose would not be acceptable. But having it under IntervalMap does not seem right either. One option would be a name change:Data.IntervalMap Data.IntervalMap.Lazy Data.IntervalMap.Strict Data.IntervalSet Data.OrderedInterval
Another is to use a general module:Data.IntervalContainers Data.IntervalContainers.Interval Data.IntervalMap Data.IntervalMap.Lazy Data.IntervalMap.Strict Data.IntervalSet
Or even put everything under that module:Data.IntervalContainers Data.IntervalContainers.Interval Data.IntervalContainers.IntervalMap Data.IntervalContainers.IntervalMap.Lazy Data.IntervalContainers.IntervalMap.Strict Data.IntervalContainers.IntervalSet
None of these seems clearly preferable, so the best option is probably to leave the package name and module structure as is.Data Structure
Preferring simplicity, I based the implementation on Red-Black trees. While this is in general competitive with size balanced binary trees as used by the base containers, there is one caveat: with plain red-black trees, it is not possible to implement a hedge-union algorithm or even simple optimizations for the very common “union of huge set and tiny set” operation unless one would use an additional redundant size field in the node.
This has become somewhat more pressing since version 0.5 where the search operations return subsets/submaps.Intervals
My initial fixed type implementation of intervals allowed mixing intervals with different openness, and type class has inherited this “feature”. I highly suspect that no one actually uses this - that is, all in instances of Interval, leftClosed and rightClosed ignore their argument and have a constant value.
If I'm wrong, and someone does use this, please let me know!
That design has a negative impact on performance, though. It turns up in the ordering of intervals and their endpoints. For example, a lower bound is actually lower than the identical lower bound of a second interval, if the first interval is closed and the second open.
Unless the compiler does whole-program optimization, it will not be able to eliminate the Interval dictionaries, and can do very little optimization. That's the reason Interval has many members that could also have been defined as module-level functions: above, below, contains, ... These functions are heavily used by the map and set implementations, and it seems that GHC at least is much better at optimizing these functions when they are defined as members (this is just an observation of mine - I don't know in detail why this should be the case). The disadvantage is that it's possible to break a lot of invariants if you actually define these members in an instance. That would not be possible if they were defined as regular functions. At least, I'm in good company, because the same applies to Eq, Ord, and Monad to name just a few.
Data.Map tries to work around this by declaring many functions to be inlinable, effectively getting a bit closer to whole-program optimization. This does not seem feasible for IntervalMap, because the functions are used as deeper nesting, and in particular when constructing nodes.
As far as GHC is concerned, good performance is very dependent on inlining, especially when type classes and their dictionaries are involved. Any improvements in this would certainly benefit IntervalMap. One idea: it might be useful to be able to provide strictness information in type classes. In the case of Interval for example, lowerBound and upperBound always evaluate their argument (disregarding really pathological instances), but there is no way to indicate this to the compiler. Only the instance declarations allow inferring strictness information, and that's not available when compiling library code.Prospects
Whether a big refactoring or rewrite should be done really depends on the users of the package: you. Please let me know about missing features or performance issues, either via mail, a github issue, or a comment here.
Lately my kids have been interested in puzzles of this type: You are given a sequence of four digits, say 1,2,3,4, and your job is to combine them with ordinary arithmetic operations (+, -, ×, and ÷) in any order to make a target number, typically 24. For example, with 1,2,3,4, you can go with $$((1+2)+3)×4 = 24$$ or with $$4×((2×3)×1) = 24.$$
We were stumped trying to make 6,6,5,2 total 24, so I hacked up a solver; then we felt a little foolish when we saw the solutions, because it is not that hard. But in the course of testing the solver, I found the most challenging puzzle of this type that I've ever seen. It is:
Given 6,6,5,2, make 17.
There are no underhanded tricks. For example, you may not concatenate 2 and 5 to make 25; you may not say and and concatenate 1 and 7 to make ; you may not interpret the 17 as a base 12 numeral, etc.
I hope to write a longer article about solvers in the next week or so.