Hacker Newsnew | past | comments | ask | show | jobs | submit | graffitici's commentslogin

Unfortunate that Joshua Tree (Yucca brevifolia) are not in there. I always thought they would have a pretty fascinating root structure because of how separated they grow. Makes sense that it’s not in a Dutch database though!


Herkese iyi seneler!


You should look into CBTI, and see a sleep therapist (my insurance covered this; so I only had to pay co-pay).

In brief, the goal with CBTI is to force yourself to get out of bed at 8am (say). You can still continue going to sleep at whatever time you’re used to. So clearly, you’ll be extremely tired if you keep getting 5-6 hours of sleep. My therapist told me that I’d essentially hate him for 1.5 weeks until this keeps going. Also, no naps are allowed in this phase. At some point, your body will be so tired that you’ll just pass out at midnight.


I guess Rust is a language that went the move to Safe and Useful, following the top arrow?


Rust prevents a few types of unsafety, mostly relating to memory and concurrency. There are many more on which Rust does not do particularly well though. Specifically, Rust allows arbitrary side effects from basically any part of the code. You can always write to stdout or a logfile, or open up new sockets, or delete files from the filesystem and there will be nothing in the type signature to even warn you about this.


>You can always write to stdout or a logfile, or open up new sockets, or delete files from the filesystem

Haskell has a separate problem here: all of these can fail, and there's nothing in the type system to alert you of this (in the standard library), such failures just mindlessly throw exceptions like some Java monstrosity. In Rust, on the other hand, all such functions return something like Either Result Error, forcing the caller to check (and ideally handle) any errors. Not to mention async exceptions in Haskell, which can happen anywhere, and the fact that every value is really of type value|undefined, due to laziness. It's practically impossible to cleanly formally reason about code in Haskell due to the fact that anywhere could be interrupted by an async exception.

When even C++ is considering trying to remove exceptions from the standard library, Haskell's love for untyped exceptions everywhere is seriously behind the times for a language that prides itself on correctness.


I used to bash Haskell exceptions but my views changed recently after programming in Haskell for a while.

> all of these can fail, and there's nothing in the type system to alert you of this (in the standard library), such failures just mindlessly throw exceptions like some Java monstrosity

There's `MonadThrow` in Control.Monad.Catch which hints that the monad in question can throw exceptions. Admittedly, partial functions like `undefined` and `error` are still usable...

> Not to mention async exceptions in Haskell, which can happen anywhere, [...] anywhere could be interrupted by an async exception

... and they can throw exceptions everywhere, just like asynchronous exceptions, but it's actually a strength! Haskell enforces a clean separation between impure code (typically in a monad) and pure code. You can only catch exceptions in the IO monad, which often lies outside of the core logic. Due to this unique strength, Haskell is one of the very few languages that can safely terminate running threads.

Impure code can become harder to write because of exceptions, but since you don't write everything in the IO monad, the problem is largely mitigated. Yes, exceptions are hard to get right, and that's exactly why other languages are trying to get rid of, but Haskell makes it quite tractable, (though still quite annoying). Rust used more Maybes and Eithers in the IO monad (to borrow jargons from Haskell), but it's also got panic, which is the actual Haskell exception counterpart.

> and the fact that every value is really of type value|undefined, due to laziness

To be pedantic, Haskell has levity polymorphism, which gives you unlifted datatypes, like in OCaml and Idris. Even older Haskell has unboxed datatypes that are not lifted.

> ...Haskell's love for untyped exceptions everywhere...

Nope, Haskell's exceptions are typed.


> > ...Haskell's love for untyped exceptions everywhere...

> Nope, Haskell's exceptions are typed.

logicchains means that the exceptions that a function can throw are not noted in its type (and as a massive Haskell fan I agree with him/her that that is very annoying).


>write to stdout or a logfile, or open up new sockets, or delete files from the filesystem

Do those things come under the category of unsafe? Why would we be programming if it weren't to do those kinds of things? If I buy a shovel, at some point I'll probably want to dig a hole with it.


Absolutely. If you watch the youtube video linked in this thread, SPJ makes that very comment, that a program with zero effects is useless.

However, the goal of haskell (and indeed any language trying to be safe in the way SPJ means) is to be able to have most code be safe/effect-free, and then to have effects be very carefully controlled and limited in their use. Things like the IO monad mean many parts of haskell code can't do IO in fact.

We obviously do want some sort of effect in the end, but the idea is it's safer to contain those effects in very limited places, and not allow effects to happen literally anywhere at any time.

Note, unsafe in the SPJ video was specifically about effects, while "unsafe" in rust terminology is mostly about memory safety, so those two terms really aren't the same word, and to be honest that can make communication less clear. I don't know what "category of unsafe" meant in your comment really.


If you'd watched the video from the grandparent comment, you'd have seen that those kind of uncontrolled side effects are exactly what Simon Peyton Jones was talking about in the video when talking about "safe" versus "unsafe" languages.

But in any case, yes those things I mentioned can fall under the category of "unsafe". In the category of memory safety, you want to be sure (with compiler guarantees!) that no thread will secretly free some allocated memory while you are still using it. This is something the borrow checker can give you in rust. There are no builtin guarantees in Rust that this fancy new library you imported won't do `DROP TABLE users`, or open a socket to https://haxorz.com and pass on all the environment variables. There are other languages in which you can be sure that a function cannot open any sockets unless it specifically has "can open sockets" encoded in its type.


> There are no builtin guarantees in Rust that this fancy new library you imported won't do `DROP TABLE users`, or open a socket to https://haxorz.com and pass on all the environment variables.

In practice that's true of Haskell as well.


Indeed, and I think it was a mistake by the parent poster to cast it as some sort of security thing. It very much isn't.[0]

Anyway, controlling side effects is really about avoiding accidental/unintentional side effects, i.e. mutating the world[1] by accident. Of course if everything is in IO, you only get "can do anything to the world" and "can't change the world at all", so Haskellers are usually interested in more fine-grained separation of effects than just pure/impure.

Of course, you are also trusting that code you're using doesn't do crazy unsafePerformIO, etc. stuff, but at least you can grep the code for that :). And sometimes unsafePerformIO can be a good thing to do 'magical' things which are referentially transparent but require mutation for asymptotics or performance generally.

[0] Safe Haskell is more about that kind of thing, but AFAIUI it isn't really in much use and never really took off. IIRC, it might even be slated for removal?

[1] Which is the ultimate shared mutable state, after all.


Right, my "in practice" was hedging for the existence of SafeHaskell, which does rely on the types and is "built in" to GHC, but as you say isn't really used by the community.


I get that. (Another way to do it at run time is capabilities). What I don't like is calling this "unsafe". We know that use after free is never something anyone intended. We don't know that about opening a socket. If we take the attitude that any effect is unsafe then soon we will feel we have to control every one of them. If I have to control everything someone else does then I might as well do it myself (i.e. you eventually start to leak the implementation details and lose flexibility). Call it contracts or capabilities or something but not unsafe.


Use-after-free is bad. "Unsafe" isn't the same as bad; unsafe means "could be bad". The reason that is a useful definition for unsafe, is that it allows us to define safe as "definitely not bad".

In Haskell, a function like 'Int -> String' is safe (definitely not bad). A function like 'Int -> IO String' is unsafe (it might be bad; we hope not). If it were possible to specify "bad" via the type system (like the type of use-after-free) then we would want that to be a type error (like it is in Rust).


I don't know. Int -> String could be bad if the algorithm that calculates the value of the string is bad. But anyway I suppose I don't like changing the use of language where "unknown" now becomes "unsafe". Unsafe to me means that I know something about it. If I know nothing about it then it is neither safe nor unsafe. It's just unknown. Why not call it that? Otherwise we have two words for the same thing and have made our language more imprecise. (Alternatively if we take the attitude that something unknown could be good then we could argue that we call it safe).


> I suppose I don't like changing the use of language where "unknown" now becomes "unsafe".

I don't think that's changing the use of language at all. For example, playing one round of russian roulette is 'unsafe'; even though (a) we don't know if it will have a bad outcome or not, and (b) the chance of a good outcome is much higher than that of a bad outcome.


I do believe that "unknown" should mean "unsafe". Safe means that you can rely on it, if you don't know anything about it then from a safety perspective this must be treated as unsafe.


Except this isn’t true. I can embed arbitrary side effects in any line of Haskell code with something like

    foo :: Int -> String
    foo x = seq
            (unsafePerformIO $
              println “pwned”)
            (show x)


Yes, we know unsafePerformIO exists, but nobody really uses it, it's clearly "unsafe", you can have your build chain scream at its occurrence, and... fast and loose reasoning is morally correct[1].

[1]: https://dl.acm.org/doi/10.1145/1111320.1111056


FYI this sort of 'backdoor' can be forbidden using the "safe haskell" extension in GHC:

https://downloads.haskell.org/~ghc/latest/docs/html/users_gu...


The point is not that you shouldn't do these things. The point is that Rust does not provide any tools to help you do it safely. Mutation is also a necessary thing in programming, which can be unsafe if done incorrectly. Rust has many built in rules for keeping mutation safe and requires labelling functions that mutate. For side effects, there is not much of a safety net in rust.


The part you missed is "always". The unsafe part is being able to do this from any function, instead of only from functions explicitly marked as being able to perform effects.


The basic idea isn't that you want to avoid such activities, but that you want to know which functions do it, so that it is easier to reason about your program.


I think SPJ is using a slightly different definition of safe than Rust does! But Rust should definitely be a bit up his safeness scale, but not all the way, doesn't fully control all effects.


It lacks a GC however, which Haskell has for a reason.


I still don't see it! Which part of the pond is it?



It was centered and zoomed in on desktop for me (are you on mobile perhaps?). Screenshot: https://i.imgur.com/ZQJMz4c.jpg


Top left. For some reason the current image on Google Maps seems to be lower resolution than the screenshot posted to the BBC.


I think different people actually get different images om Google maps..


Google has two sets of base images. I usually prefer the plain 2D images, but you can get their reconstructed/interpolated 3D view with false color by toggling the "Globe" option in Google Maps, or the "3D Buildings" option in Google Earth. At this particular location, the 3D view has higher resolution.


Yeah, enabling 3D view makes the car plain as day, even on Firefox.


I think you are correct because the screenshot someone posted above in Imgur is not what I see on google maps.


I can confirm. They might use your origin account country?


I can getting 2 images taken at different times when I am using Firefox or Chrome.

The Chrome one seems to be much higher quality.


Hey Google, is serving a lower-resolution image to Firefox part of leveraging a monopoly against Firefox?

Is your legal team fine with that? Is there any legitimate reason anyone could possibly identify for why you would purposefully worsen the experience for a fully compliant browser like Firefox, by lowering the resolution?

What does your legal team have to say about this?


You can get the better version in Firefox if you click Globe in the menu on the left.


thanks. do you work for Google?


No.



I think its top left corner of the pond, it seems to be parallel with the edge of the pond


Looks like at the bottom left.


But someone can write a proxy that exposes Gmail as a JMAP endpoint?


There already is one, written by the people behind JMAP even, with a public demo instance at https://proxy.jmap.io/ (don't use the demo with your own credentials of course, host it yourself)


"Given to me or bought with book tokens"

Book tokens?! Is this some kind of 40s cryptocurrency?


Seems like an early kind of gift certificate scheme. https://www.theguardian.com/lifeandstyle/2007/nov/17/weekend...


We still have book tokens here (Ireland). They're a gift voucher that's only redeemable for books, and not tied to a specific shop


They were/are much prized as an 'improving' birthday present or prize for children.


I love the combination of these! Really opens up a world of possibilities. The one command I'm still trying to replace is `cd` itself. For instance, can anyone suggest a way to add bookmarks, so that I can move around faster? I found a few, but was never happy with them.


I use a combination of https://github.com/clvv/fasd and https://github.com/ranger/ranger.

When tasks like navigating into a project, starting tests, local server and neovim become repetitive I usually end up making a tmux script which does everything for me.

Also, aliasing ‘..’ to ‘cd ..’ and such.


Probably not exactly what you want, but the pushd/popd/dirs commands have existed in all major shells forever.

You can run dirs -v to get the list, and do cd +(num) to go there.

So:

  FreeBSD <jubei/pts/2> (219 /var): dirs -v
  0	/var
  1	/usr/local
  2	~
  FreeBSD <jubei/pts/2> (220 /var): cd +1
  /usr/local
  FreeBSD <jubei/pts/2> (221 /usr/local): _


I’ve been enjoying autojump [1], it automagically creates bookmarks and prioritises them based on frequency of visiting said folders.

[1] https://github.com/wting/autojump


Autojump is the answer here. Totally a gamechanger. If you like its semantics enough, check out fasd [1] , which is a superset of autojump that applies its cache in many other places. Absolutely awesome.

[1] https://github.com/clvv/fasd


The $CDPATH variable (built into `cd`)[0] plus the `bash_completion`[1] script to enable tab-completion of CDPATH dirs - works for my use case (FWIW).

[0] http://linuxcommand.org/lc3_man_pages/cdh.html [1] http://www.caliban.org/bash/index.shtml#completion


I recommend https://github.com/clvv/fasd It basically makes bookmarks automatically as you navigate your filesystem anyway.


Scratched that itch of mine for bash/zsh in 30 lines[0]. kd stands for quicKDir or worKDir depending on the moon.

    kd foobar ~/Workspace/foobar  # define bookmark
    cd ~/some/where
    kd foobar                     # goes to bookmark
    kd foo                        # matches on string prefix, last entry wins
    
    cd ~/Workspace/quuuuuux
    kd qux "$PWD"                 # quick bookmark current dir
    
    touch Gemfile                 # define project root
    cd app/controllers/name/space/whatevs
    kd                            # goes to project root
Turns out autojump doesn't work for me, too many projects in parallel. Since this one is manual, it can be very semantic. Those 30 lines saved me hours on end of tab mashing, especially in Go workspaces.

[0]: https://github.com/lloeki/dotfiles/blob/master/shell/kd


http://cryptonector.com/2007/04/c-shell-pushdpopd-on-steroid...

I have been doing something similar for many years. Someone ported this to Bash... I'll try to get that port up on github.

EDIT: https://raw.githubusercontent.com/jakobi/script-archive/mast...


It isn't super clear in the article, but I now use bfs & fzf for replacing cd.

https://github.com/bag-man/dotfiles/blob/master/bashrc#L73

Lets you change directory with alt+c, although I have tweaked it so you always search from your root folder. Which isn't for everyone. Otherwise fzf alt+c doesn't let you go back up directories which gets frustrating.


Hey, bfs author here, glad you've found it useful! You can do that whole thing in one command with

    bfs ~ -nohidden -type d -printf '~/%P\n'


I've just tried this and in my case it leads to "cd \~[...]" which obviously does not work.


That's strange. Maybe just change it to:

    export FZF_ALT_C_COMMAND="bfs -type d -nohidden"
(and install bfs of course)

It won't let you go back up the tree, but if you are clever you can use `cd -` to jump back to your previous location.


https://github.com/rupa/z could also be interesting for you.


Also interesting is fzf-marks:

https://github.com/urbainvaes/fzf-marks.git


I have a little script that combines z and fzf.

https://gist.github.com/chew-z/44f3bcdc08eaecdf306868f9a3d0e...


> The one command I'm still trying to replace is `cd` itself.

zsh will implicitly cd if you just mention a directory e.g. `$ ../foo/bar [RET]` will cd there without mention. These days I only use `cd -`.


> These days I only use `cd -`.

There's also `cd foo bar` in zsh, which substitutes foo with bar in the name of $PWD. I rarely used it, and when I do, it's usually for a well known pair of lengthy named dirs, yet it also shaves off a couple of keystrokes pretty much daily for me.


IIRC that isn't the default. You need to enable the option for that to work.

zsh has about a thousand options you can configure.


> IIRC that isn't the default. You need to enable the option for that to work.

You're right, it's been so long I completely forgot.

It's auto_cd, and auto_pushd will also automatically push new directories to the dstack.

> zsh has about a thousand options you can configure.

I should probably go through the options list in its entirety one day, but technically according to http://zsh.sourceforge.net/Doc/Release/Options.html it's closer to a quarter of that ;)


I think it is enabled by default. I never explicitly enabled it for my zsh configuration and it behaves that way.


This is fantastic news. If I understand things correctly, we can now host the Wire server on our own VM, and use the clients to connect to it, correct? We'll have full control over the end-to-end encrypted network?


No most of the source is still missing.


Really cool video! Can anybody guess how much it may have cost them to make?


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: