Ply: A Visual Web Inspector (2018) [slides] - <AUTHOR> https://slim.computer/ply-uist-2018/#/title-slide <comment><USER2> Here's a PDF paper of the same topic [http://users.eecs.northwestern.edu/~hq/papers/ply.pdf](http://users.eecs.northwestern.edu/~hq/papers/ply.pdf)

and Github:

[https://github.com/sliminality/ply](https://github.com/sliminality/ply)

"Several of Ply's core features have been released as Inactive CSS in Mozilla Firefox 70."

</comment><comment><USER3> Neat, it would be an interesting linting tool to help minify CSS. I was wondering why the pruning tool took so long but I can see they are using visuals to determine if a a style is needed or not. That's a really smart way to do it, I wonder what other use cases there are for mapping visual images to code. This is almost like a selenium test for CSS.

<comment><USER4> I wonder how broad the definition of effectiveness is in their implementation. The visual method might have limitations, considering that many CSS properties are only "effective" when you start moving/interacting with elements, e.g. resizing the window/elements, or hovering over elements or using other cursor actions.

<comment><USER5> Looks like good ol' screen diffing. It may be possible to use heuristics to detect when a rule might be important for layout in other configurations but this is _probably_ good enough for the stated purpose of highlighting what CSS is important for learning.

</comment></comment></comment><comment><USER6> What happens in the case where you have two properties, A and B that "work together"? For example disable A and visually the element stays the same, disable B and visually the element stays the same, but disable A and B and the element changes (and based on the way you regress it might falsely tell you that A or B is effective depending which one you disable latest).

</comment><comment><USER7> I like the idea but I think it's applied in the wrong end of the stack. Learning that z-index requires a defined position value is just part of learning CSS, however frustrating that may be. The answer to the question "How do I make a form like this?" is one that involves the pros/cons of using flex or grid or floats or tables, class name hierarchy, style inheritance, etc. Instead, what we have are junior devs thinking "I know how to do this with Material UI but I've never done it from scratch" so they search for 'booking bar layout' and only learn how to tweak other people's code and not have the confidence in writing their own. What's worse is that this tool is further encouraging devs to reverse-engineer first and learn later, rather than learning as you engineer.

<comment><USER8> It's exceedingly common that programmers don't know how to do frontend web development, but are tasked to do it anyway, often with unrealistic time constraints. Tools that help them achieve their objectives successfully are always welcome.

"Learning CSS" is a years-long pursuit, and it's constantly evolving. I was a frontend developer most of my career (and by all accounts a pretty damn good one), but I've spent the last four years almost completely on backend work. I have some frontend work coming up and I am honestly nervous that it will take quite a bit of time and consternation for me to become productive with whatever has changed. (It's almost certain I'm going to need to learn grid, who knows what else.)

Am I going to look to a tool like this to help me get back up to speed? You bet your ass I am.

</comment></comment><comment><USER9> Looks cool. On the other hand having to figure out what CSS properties do and dependencies I think has helped in the long run. This seems like a tool that is good for short term success but may slow down long term success.

</comment><comment><USER10> I appreciate the effort in improving CSS dev tools. I rely on them a lot, and just looking at those slides you can see how difficult of a problem it is to solve.

Flexbox and CSS Grid have introduced another level of complexity, in that, the display value of an element turns its direct children into flexbox/grid elements, making their display value irrelevant. It also makes their flex-* properties effective. You'd have to parse the DOM tree to detect such dependencies.

Also, pruning innefective properties isn't that easy because you need to take into account the context. Let's say you have a blue button with white text. This button is in dark navbar that also has white text. Apparently, the button's color is ineffective because inheriting its value from the navbar would suffice. But that same button in a dark text context would make the color property effective again. Since the button would have the same CSS class, you can't prune the color for all instances.

Definitely a hard problem to tackle.

</comment><comment><USER11> With the "pruning" feature I see a possible path for advanced minification in CSS and possibly in other parts of the web stack. Instead of having each element inherit from several classes, a build step could reduce all dependencies on each element and pack an optimized CSS file while ensuring visual integrity.

<comment><USER12> Would you not then need one css file for every permutation of app state, window dimension and possibly device type?

<comment><USER12> That's not even mentioning scroll state or mouse position

</comment></comment></comment><comment><USER13> I like this. One of the things that has always bugged me about CSS is that after a few iterations you get non-obvious interactions between rules.

In fact, I'd love to have a CLI tool that would take a website (or a set of CSS files and a sample HTML layout) and spat out the minimally effective CSS required for it — an optimizing compiler, if you would.

<comment><USER14> Even though it's not a compiler, SingleFile [1](and SingleFileZ [2]) can do that. It will compute the cascade, remove almost all the unnecessary rules, and minify the CSS.

[1] [https://github.com/gildas-lormeau/SingleFile](https://github.com/gildas- lormeau/SingleFile) [2] [https://github.com/gildas- lormeau/SingleFileZ](https://github.com/gildas-lormeau/SingleFileZ)

</comment></comment><comment><USER15> This is neat. Kinda related: For anybody new to CSS (or anybody that just finds it a pain) I found using Tailwind CSS upped my design game.

Using a limited number of selectors helps you reason about what each property is doing and highlights how many superfluous properties you've been using to accomplish what could be done rather simply.

</comment><comment><USER16> Really neat tool.

So the way Ply works is it deletes each CSS property and looks for visual regression; but what if the deletion of a CSS property introduces visual differences only under certain screen sizes due to the use of media query?</comment>


My favorite Erlang Program (2013) - <AUTHOR> http://joearms.github.io/2013/11/21/My-favorite-erlang-program.html <comment><USER2> What I found interesting (or very, very boring, depending on how you think about it) about this when I first saw it is that this ability is just due to the nature of how receive works. That is, you can receive any kind of message, at any time. Want to listen to a different set of messages? Just call a different receive clause, be that in a different function, or inline.

I remember having a coworker who was in love with Akka. He was trying to sell everyone on it, despite my team's having a strong Erlang presence. He showed us Akka's "become", talking about how powerful that could be, and how Erlang didn't have anything comparable. He didn't seem to realize that Akka's needing a special keyword for it was actually a limitation rather than a feature, that Erlang didn't have a special keyword to allow you to do it because it didn't -need- a special keyword to allow you to do it. That's not a dig at Akka, or Scala (it's an impressive language in its own right), but rather to point out how sometimes we miss the complex capabilities a simple set of abstractions can give us.

<comment><USER3> Re: Akka, to paraphrase James Gosling's comments on Java "We brought a bunch of Java programmers halfway to Erlang".

<comment><USER4> FYI that wasn't Gosling, that was Guy Steele: [http://people.csail.mit.edu/gregs/ll1-discuss-archive- html/m...](http://people.csail.mit.edu/gregs/ll1-discuss-archive- html/msg04045.html)

<comment><USER3> My mistake! And in retrospect, Guy Steele saying that makes way more sense.

</comment></comment></comment></comment><comment><USER3> We've been experimenting with Elixir at work, and it's been really cool to drop down into the Erlang ecosystem and see how people think when they're designing OTP programs, especially when it comes to things like Riak and Mnesia and those sorts of things. My only complaints about this ecosystem is that everything feels scattered in specific places (I've had to read a lot of books, versus being able to read tutorials) and that it's very hard to tell an abandoned project from a feature complete project on GitHub. You can generally look at downloads in the Hex package manager for a rough idea of popularity, but then again build servers can inflate unpopular packages. Someone in the Elixir slack joked to me "75 stars? That's super popular for Erlang!". I can deal with it, but I wish it weren't so.

All that said, I think I'm going to stick around with these languages. Everything feels very well designed and battle ready, in stark contrast to using JS. Elixir also seems to remove a lot of the cruft and awkward syntax of Erlang, and having Lisp-style macros makes the GenServer boilerplate go away entirely.

<comment><USER5> Elixir did make Beam/OTP more accessible and more "fun" :)

<comment><USER6> Fun is in the eye of the beholder. I'm worried that Elixir will take off because it's "hip" and ruin the chances for other people to use a pure and consistent language (Erlang) at work.

It is amazing what kind of middleware bloat is forced unto people these days.

<comment><USER7> One could argue that Erlang/OTP has had decades to be used at work, and no one wanted to (sadly). Elixir taking over doesn't affect Erlang because Erlang wouldn't had become more popular over time anyway.

<comment><USER8> I personally am doing BEAM now mainly because of Elixir. It's undeniable that a "hip", and let's face it, young, crowd, having chosen Erlang/BEAM, gives it a big breath of fresh air (this is NOT to insult the experienced Erlang devs - it's just a fact that a new young crowd choosing your tech is an endorsement). Interestingly though, I'm more and more intrigued by the underlying technology. Personally I am not a fan of some of Elixir's design choices f.() versus f() for example, and maybe, just maybe, I'll do Erlang now.

Overall though, it was a total blast the other day to just run 10 000 processes so easily, within milliseconds, and watch all my cores go to max without messing with threads or even the (somewhat obtuse) Go channels. Actors really are easy to reason about. I like this model so much that I'm even looking at it for C (C++ Actor Framework).

<comment><USER9> I'd be interested to hear about your experience with the C++ Actor Framework. It seems like without the larger ecosystem of Erlang/BEAM for fault tolerance CAF is just a nice coroutine library.

</comment></comment></comment></comment></comment></comment><comment><USER10> "It is no exaggeration to regard this as the most fundamental idea in programming: The evaluator, which determines the meaning of expressions in a programming language, is just another program." \-- Abelson & Sussman, SICP.

</comment><comment><USER11> What I find amusing about this is that raw receives are actually kind of frowned upon in the Erlang community, but the creator is still using them, and the language is still kind of beautiful and cool.

This isn't in any way to talk negative about Joe Armstrong or Erlang, but more to show how cool the language is: even non-idiomatic code scales and is wonderful.

<comment><USER2> Slightly tangential, but, I think it's more not using gen* in a supervisor hierarchy is frowned upon. Using raw receives within ~that~ sometimes is the right solution.

For instance, I had an instance where I needed to serialize requests out to an external piece of hardware. Various user or system events would determine hardware control events that needed to be sent out, and then responses needed to be listened for to determine if they were successful or not, and return that error the user. Essentially an asynchronous, but serial, process. I had a gen_server to synchronize access to the hardware.

Now, the way I implemented this was, with each call that came into the gen_server, I'd send a message via gen_tcp, and then listen for the response as a raw receive inside of the same call. The alternative, to stay in the gen_* structure, would have been to send and finish, and then handle the response in the handle_info (since gen_* is coming back as a raw message). But that would have allowed more sends to occur in between the initial send and getting a response back, which would break the serialization we needed to ensure, and would have lost the reference to who had sent the initial request (since I was reusing the socket, and the acknowledgements from the hardware didn't include any sort of session), making it impossible for me to respond properly to the original caller.

So with a raw receive in there, it effectively became like a 'become' server, in that at the top it was a gen_server that implemented a gen_tcp "send" server, and then after sending it temporarily took on the characteristics of a gen_tcp "listen" server via a raw request (though obviously it was listening on the socket even before sending), before reverting back to the "send" server that waited for the next thing to send.

In fact, as I recall, while we were serializing our sends, there were certain types of events being broadcast by the hardware that we needed to drop even in the raw receive, so it was recursive. That is, our send server became a listen server, and stayed as a listen server until either we got the response we wanted, or a timeout was hit, at which point we'd revert back to the send server.

<comment><USER12> This is exactly how we are using a raw `receive` in one of our production systems -- multiple asynchronous, but serial within, processes.

Thanks for sharing this. It gives me more confidence in what we have done!

</comment></comment></comment><comment><USER13> How would this program look like translated to Haskell?

<comment><USER14> id

(I'm about two-thirds joking)</comment></comment>


Show HN: Play – Insanely fast music video player - <AUTHOR> https://play.cash <comment><USER2> I like the interface and overall design a lot. But for the player, there isn't a dedicated full screen button, nor is there volume control, two things that for music videos and music in general are pretty much needed.

</comment><comment><USER3> The interface seems very responsive, but what makes it "fast"?</comment>


3 Stupidly Simple Ways To Automate Your Business - <AUTHOR> http://www.automizeit.com/blog/3-simple-steps-to-automating-your-business New blog post I just wrote up showing you the 3 step process for automating your business. It's what we go through on a daily basis to "step away" Please SHARE or ReTweet! :) <comment><AUTHOR> We go through this process each time we want to automate something.

1\. Systemize it 2\. Automate it 3\. Optimize it</comment>


Shale Gas Turns the Tables on Petroleum Powers - <AUTHOR> http://ipsnews.net/news.asp?idnews=106359

<comment><USER2> While I find the geopolitical ramifications interesting from a power-gaming standpoint, what is really interesting to me is the energy reserves of the planet (in terms of fossil fuels) is so fungible.

To the extent that we are successful at transitioning to electricity as the primary energy 'currency' I expect it will allow an ever widening array of technologies to contribute to the net energy 'pool'.

</comment><comment><USER3> I seem to remember that some time in the 80's or 90's, (could have been earlier) that the FEDs finally made the connection between injection wells on (I think) haz-mat sites and tremors in Denver. The comparison between that and Ohio's current hold on fracking may or may not be related, but it does give one pause to speculate...</comment>