HN user

jaspervdj

484 karma
Posts17
Comments41
View on HN

Limiting access helps, but if you are storing the logs on a 3rd party (e.g. DataDog, CloudWatch), you will still need to assume it can leak through that 3rd party and start rotating.

If you wanted to log from fibonacci, you would pass a some logger instance down to this function. In Haskell, this could be a record or a typeclass instance. In other languages, it could be an object or a struct. There is no fundamental difference. All the layers above would still have to pass this through; explicitly or implicitly.

The builder interface has important performance benefits over working with lists: similar to e.g. concatenating many small Strings vs using StringBuilder in Java.

The builder interface indeed does not need to be monadic, you can simply append things using <> and get the same benefits.

The monadic interface is purely a syntactic enhancement on top of that, to reduce the number of operators you need.

Clicking and keyboard work on the computer, and tapping and swiping works on touch devices. I was hoping this would be clear enough since I don't want to take up people's time with tutorials. Maybe we can add a separate "help" button or add this to the about page?

I'm not sure if this is the same issue but we've heard from tons of people that the "undo" button should be at the bottom in order to make it easier to reach using a phone one-handed. We've now made that change. If you're referring to something else, please elaborate :-)

Not really, if you wanted to do a version using only immutable arrays:

  import Data.Array
  
  fw :: Int -> Array (Int, Int) Int -> Array (Int, Int) Int
  fw 0 graph0 = graph0
  fw k graph0 =
    let fw' = fw (k - 1) graph0 in array (bounds graph0)
    [ ((i, j), min (fw' ! (i, j)) ((fw' ! (i, k)) + (fw' ! (k, j))))
    | (i, j) <- range (bounds graph0)
    ]
The only difference with a mutable implementation is that you use a new array for every k, whereas in a mutable version you would reuse these.

Explanation in this comment: https://github.com/bountysource/core/issues/1147#issuecommen...

  On July 27, we reached out to Bountysource in response to a complaint we
  received from a user. During our investigation and discussions with members of
  your team, we found that your organization does not have a mechanism for
  responding to removal requests from users, which is required by our Terms of
  Service. Specifically, Bountysource does not "respond promptly to complaints,
  removal requests, and 'do not contact' requests from GitHub or GitHub Users."
  Over two months later, you have not made any changes to your platform in
  response to our requests.
  
  Therefore, we have suspended your application until you create a process for
  actively responding to all personal information removal requests, including
  those related to projects and issues. In order for us to remove the
  suspension, we would ask to see two things:
  
  1. Confirmation from you that you have a process in place for responding to
  takedown requests about all areas of your website.
 
  2. Inclusion of a public notice to your users stating how to request the
  removal of information. That notice can be included in your documentation or
  other legal notices.
  
  Once you have that process and public notice in place, we'll be happy to
  review your site and consider lifting the suspension.
Sounds like it's (hopefully) not permanent.

I don't intend to make money with it, but yeah I found it to be pretty useful if I want to give quick-and-dirty presentations to other engineers or technical folks. It basically allows me to switch between the presentation and a demo (running in the console) more seamlessly.

For my particular use case: I work remotely and we use video conferencing all the time. Our video conferencing software allows you share a single screen which is neat, but annoying if you need to switch between a browser (or PDF viewer) and the terminal.

I wouldn't use it for "proper" presentations, or stuff that needs a lot of math (LaTeX beamer comes to mind for that).

Not sure, I assume so. I think it was part of a bunch of SSGs imported from another listing.

    https://github.com/jaspervdj/static-site-generator-comparison/commit/96f23ed30db97067feb42b2f9100ec48c2596eb6

I like the additional info on that site! Would you want to consolidate efforts and use:

    https://github.com/jaspervdj/static-site-generator-comparison/
as an underlying list, too? Maintaining a listing is pretty tedious with all the SSGs out there. I can set up web hooks and whatever to push to your servers if the listing changes.

You're right, thanks!

    https://github.com/jaspervdj/static-site-generator-comparison/commit/610b1b35742a281a84bfb18cf026842d1b92bf67
  GET jaspervdj.be/lorem-markdownum/markdown.txt?allow-headers=true&allow-code=true&allow-quotes=true&allow-lists=true&inline-links=true&hash-headers=true&asterisk-em=true&asterisk-strong=true
Let me know if you run into trouble. :-)

This is not the case, not by far. nanoc is aimed at building complex sites and hence has a lot more features than Stasis. Some examples:

- Items can contain arbitrary metadata in nanoc

- You can trivially build multiple representations of a single item in nanoc (e.g. a PDF/txt/html representation of a single markdown file)

- Dependency tracking in nanoc is fully automatic (no need to specify priorities)

- Nanoc is easily extensible using custom filters, custom deployers, custom helpers and more

Statis and nanoc have a different audience. To me, Stasis seems to be aimed at simpler, smaller sites, while nanoc is aimed at much more featureful sites. It is a good thing to have a lot of documentation (nanoc is frequently cited as a good example of how documentation should be handled).

I'm pretty sure there will be no overhead from the type class when the appropriate SPECIALIZE and INLINE pragmas are added, and compiled with -O2. I haven't taken the time to optimize it yet because I haven't had performance problems so far.

Your Vector implementation should offer roughly the same performance. It might be an unnoticeable bit slower because Vector does bounds checking, and my Memory module doesn't (out-of-bounds access is impossible because of the ADT I added).

One thing I'd like to comment on is that I think you should revise your use of unsafeThaw/unsafeFreeze: you don't easily get guarantees of determinism when using these unsafe functions.

> To me, it looks like you haven't "done" anything at all. You haven't emulated a single instruction. This part of the emulator in C++ would be a couple of structs and helper functions thrown at the top of the file.

It seems there's a bit of a misunderstanding. The code in the blogpost consists of incomplete snippets, taken from the actual implementation, found in this repo [1], e.g. the emulator [2]. The reason why I have not included the entire codebase in the blogpost is conciseness; I only wanted to include what's necessary to illustrate the points I wanted to make. I realise this is perhaps a bit unclear and I'll update the post to state this more clearly.

> As far as I can see, you've just written a bunch of very complicated code and monads, to get you to place would would have started at in a non-functional language. In that case, what exactly have you gained by using Haskell at all?

As much as you would gain by implementing a basic skeleton in any language. In this case, what the blogpost focusses on, is that I have written two backends ways, the ST and the IO one.

The advantage of the ST backend is that is guaranteed to be deterministic (which is possible in Haskell): the code cannot perform any side effects visible to the external world.

The IO backend does not offer this guarantee, and needs to be able to communicate with the outside world in order to grab keyboard events and display video.

The advantage of using the monadic abstraction is that the actual emulator implementation is the same (completely shared code) for both these backends. This allows you to e.g., get deterministic results for tests, while still being able to support all features in the actual emulator binary.

The deterministic property is an advantage of using Haskell. I am sure an equivalent of the monadic abstraction could also be implemented using some OOP system.

> P.S. Sorry if this comment comes across as insulting / argumentative. I do not have the time to write it in a more pleasing way.

No insult taken.

[1] https://github.com/jaspervdj/dcpu16-hs [2]: https://github.com/jaspervdj/dcpu16-hs/blob/master/src/Emula...

Yes it is, it would work fine as a variable. E.g.

  var lenght = 23;
  console.log(lenght);
will not cause any troubles. And many of the results returned by the search are of this kind.

Hakyll 3 is mostly inspired by nanoc. The key differences between nanoc and Hakyll are:

* type-safety of Haskell prevents you from doing I/O where this could be dangerous;

* while nanoc layouts can contain code (erb), Hakyll templates do not support this -- all code needs to go in the Haskell configuration file;

* Hakyll uses pandoc for document reading/conversion, nanoc usually uses kramdown and other ruby libraries;

* Nanoc uses a separate DSL for "routes" and "compilation rules", in Hakyll these are defined in the same DSL;

A more in-depth comparison would indeed by very handy. The author of nanoc lives near me, so I'll see if we can come up with a decent comparison together.