If your type system is HM, consider a compositional type system instead, for much better explainability of type derivations and type errors: https://unsafePerform.IO/projects/talks/2016-06-compty/CompT...
HN user
gergoerdi
http://gergo.erdi.hu/
Debugging via high-level simulation is something my book spends a lot of time on. If you look at the sample chapters, you can see that the same Clash code can also be compiled into software Haskell, which you can then interface with non-synthesizable test benches, such as an interactive SDL frontend. So you can take your HDL logic and run it directly, interactively in real time. You can play Pong by compiling the code as software.
One level lower, you can use Clash's signal-level simulator. Basically it gives you a synchronous stream of signal values, either as a lazy list (for "offline" simulation), or as an automaton that you can turn the crank on by feeding it the next clock cycle's inputs (for "online" simulation, i.e. where you want to do IO to compute the next input from the previous outputs). So at this level, you'd take your Pong circuit and use the automaton interface of the simulator to feed the virtual "pushbutton" states computed from e.g. keypresses, and then consume the output to do the rendering. Or simulate the whole circuit end-to-end and feed its output into a VGA interpreter, which you also get to write in Haskell.
If you need to debug at the Verilog level, you can use Clashilator (https://github.com/gergoerdi/clashilator) to automate FFI-ing into a Verilator-generated simulation.
Your website is of course referenced in the Compucolor II chapter of the book. It was invaluable in getting my Compucolor II implementation working. In fact, I even sent you a PR to fix the TMS 5501 chip's behaviour to match its datasheet (https://github.com/jtbattle/ccemu/pull/2/).
I chose the Compucolor II for its simplicity. Its original design goal of cheapness via very small number of components translates is a big win for my purposes because implementing many small special-purpose chips would bloat the book considerably, without adding too much extra value. With the Compucolor II, we can just take the Intel 8080 core from an earlier chapter, implement two custom chips, take the UART from another earlier chapter, and boom done.
In fact, I chose the Intel 8080 in the first place instead of the more widely used Z80 for the same reason: adding the Z80 extensions wouldn't bring anything new to the table, but would increase cruft. Turns out there's a small but reasonable number of 8080-based home computers (https://retrocomputing.stackexchange.com/q/11682/115).
In the book (see the sample chapter 8 at https://unsafeperform.io/retroclash/#samples) we create a proto-almost-game (just a bouncing ball) first by directly wiring together signals.
However, the resulting circuit description is much harder to understand and extend than a more structured approach, so we rewrite it in a more principled manner by decomposing it into two parts: a `Input -> State -> State` circuit used as a register transfer enabled by the start of the vblank, and a `State -> Coordinate -> RGB` circuit connected to the video output signal generator. This has the added benefit that we can compile the same description as software Haskell instead of hardware Clash, and so we can use high-level simulation to run the bouncing ball in an SDL window.
Sample chapter 9 then creates a Pong game by just changing these two (pure, Haskell) functions slightly. With minimal changes, we go from idle animation to playable game!
Previous discussion on HN about Clash itself:
https://news.ycombinator.com/item?id=23096338 https://news.ycombinator.com/item?id=9516217
That's cool! I wanted to avoid having to build Rust and/or LLVM from source myself, hence the somewhat awkward "tell Cargo we're on default target, let Clang sort it out at link time" setup.
From what I understand, LLVM-MOS treats large parts of the zero page as virtual ("imaginary") registers, so you have no shortage of that (https://llvm-mos.org/wiki/Imaginary_registers). Then, sufficiently advanced compiler technology improves the stack situation (https://llvm-mos.org/wiki/C_calling_convention).
Did you look at chirp8-engine, or only chirp8-c64? The value add is not in the parts that interface with the C64 internals; probably using C for that would make for nicer code. But I wanted to push as much into Rust as I could in the short amount of time I spent on this.
The real advantage of using Rust is in the actual program logic. E.g. the instructions are decoded into an algebraic datatype (in https://github.com/gergoerdi/chirp8-engine/blob/7623353a8bf0...) and then that is consumed in the virtual CPU (https://github.com/gergoerdi/chirp8-engine/blob/7623353a8bf0...). Rust's case-of-case optimization takes care of avoiding the intermediate data representation at runtime.
They could put a tiny microcontroller that has a USB HID host and translates to PS/2 connected to the FPGA. So you have a USB socket on one side, you plug your normal USB keyboard or mouse into it, then that socket is connected to the microcontroller, and there are two wires (PS/2 clock and data) connecting the microcontroller to the FPGA.
Some hobbyist and educational FPGA dev boards do that, because handling PS/2 on the FPGA is so much easier than raw USB. Here is one example: https://reference.digilentinc.com/reference/programmable-log...
"The Auxiliary Function microcontroller (Microchip PIC24FJ128) provides the Nexys A7 with USB Embedded HID host capability. "
HoTT isn't a programming language, because there are non-value normal forms. That's the whole reason behind research into various formulations of Cubical Type Theory, which is a programming language.
I think at this point, Haskell is the most likely to become the first mainstream PL with Pi types: https://gitlab.haskell.org/ghc/ghc/-/wikis/dependent-haskell
As an alternative to Hindley-Milner, also consider a compositional type system (https://unsafePerform.IO/projects/talks/2016-06-compty/CompT... it should be a very good match for the kind of simple HM type systems that you're going to encounter while learning about compilers.
Here's code if you prefer that to slides: https://github.com/gergoerdi/hm-compo
Here's a toy example: a single-page web app written in Idris. https://github.com/gergoerdi/icfp-bingo-2017-idris
No, it is Ancient Greek, not Latin.
I've found that building the Lego Technic Porsche 911 set from a couple years ago really helps a lot with understanding dual-clutch transmission systems. https://brickset.com/sets/42056-1/Porsche-911-GT3-RS
The problem with advanced type inference is that the exact algorithm needs to be part of the standard for compability reasons
I don't think that's true -- if you have principal types, you can just say in your language spec that the principal type is inferred.
If `x` is a representation of a real number, how do you compute if it is above or below 2? Suppose you start computing its digits, and you get 2.0000000, you don't know if you will get a non-0 digit later if you keep computing.
Which example do you think uses term-level variables more than once?
As a positive example, GHC has tests that are run for PRs that check performance (in terms of memory allocation): https://ghc.haskell.org/trac/ghc/wiki/Building/RunningTests/...
And here's a worked example of applying this approach, in this case to the domain of video editing: Super 8 Languages for Making Movies (Functional Pearl) https://www2.ccs.neu.edu/racket/pubs/icfp17-acf.pdf
*Kovacs.
This seems like a real-time / on-line version of MagicHaskeller: http://nautilus.cs.miyazaki-u.ac.jp/~skata/MagicHaskeller.ht...
So can someone use this to show us where the rifle is on the turtle?
There's this local example in Wikipedia: https://en.wikipedia.org/wiki/Mandelbrot_set#/media/File:Man...
I can't not plug Peter Divianszky's implementation at https://hackage.haskell.org/package/minesweeper which has the awesome property that the board is generated as you play, in such a way that you never have to guess (in the sense that if a field is not forced by currently shown clues to have a mine, then it won't have one when you click on it).
One drawback of the Hindley-Milner type system is that its typecheckers are necessarily non-compositional. The basic idea here is that this can result in "non-symmetrical" error messages[1]: given something like
MkPair :: a -> b -> Pair a b
not :: Bool -> Bool
succ :: Int -> Int
foo x = MkPair (succ x) (not x)
the error message will either complain that `x` has type `Bool` but it should be `Int`, or it will complain that `x` has type `Int` but it should be `Bool` -- depending on what implementation you use! For example, in Haskell, Hugs 98 will emit the first error message, but GHC 7.10 will emit the second (see the full example in my slides[2]). And in some sense, neither is right (and certainly neither is as helpful for the programmer as it could be).So next time you're implementing vanilla HM, maybe consider a compositional type system[3] instead, which can give the following, much more informative error message:
Cannot unify 'Int' with 'Bool' when unifying 'x':
Cannot unify 'Int' with 'Bool' in the following context:
MkPair (succ x) (not x)
Bool -> Pair Int Bool Bool
x :: Int Bool
I have a simple implementation here[4], and am about to release a new version which works on `haskell-src-ext`'s AST to support more of Haskell 98 syntax (but still for vanilla HM only).[1] https://gergo.erdi.hu/blog/2010-10-23-the_case_for_compositi... [2] https://gergo.erdi.hu/talks/2016-06-compty/CompTy.pdf [3] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.25.8... [4] https://github.com/gergoerdi/hm-compo/blob/master/src/Langua...
Non-Recursive Make is also Considered Harmful: https://news.ycombinator.com/item?id=11441719
In seriousness, the linked paper describes Shake, a Make replacement with two party tricks: one, it is implemented as a DSL embedded in Haskell, thus giving a nice way of programmatic rule generation; and two, it supports monadic dependencies, unlike Make's applicative-only ones.
I've used Krakatau, a JVM assembler / disassembler written in Python, to good effect in a project: https://github.com/Storyyeller/Krakatau
We need much more of #3 than what we have. In relative terms, it seems #3 is shrinking on the Internet over the decades.
That is a much more complicated question than you make it sound: https://cstheory.stackexchange.com/q/5245/1802