proj-oot-ootLibrariesNotes5

 rdtsc 12 hours ago [-]

> Implement backpressure throughout your system.

This is a subtle one and gets lost among CAP theorem talk, but it is important.

Just recently had to struggle with adding backpressure. Did some things as just sending a message (a "gen_server:cast" in Erlang). The sender shoved all 300K+ messages in the mailbox of receiver which could not process them in time because of a bottleneck and bug. Receiver's memory usage went to 120GB when it eventually restarted.

The simple solution was just to switch a gen_server:cast with a gen_server:call i.e. make the receiver acknowledge, and the sender wait for acknowledge before sending another message. (As an aside that's the nice benefit of Erlang/Elixir there, it was really a 2 line change. If it was some kind of serialization library + rpc socket layer, it would have been a lot more code to write).

...

sitkack 9 hours ago [-]

This isn't backpressure, this is forcing synchronicity by using a queue depth of 1. For low throughput applications this is fine, but the latency will kill you on the long run and vastly underutilize available resources.

Backpressure should be proportional to the amount of work you want to prevent. And that backpressure should propagate up the event stream to limit the whole capacity of the subgraph. The slowest chain governs the speed of the whole system so that it can retain functionality instead of falling over. Which relates to other properties of the system

reply

rdtsc 9 hours ago [-]

You can think of synchronicity as the most basic form of backpressure. The goal is to avoid flooding the target when source sends at a too high of a rate.

But that was a quick fix. Eventually I implemented something else. Notice that in my case there was a also a bug, so it wasn't just due to normal hardware limits.

...

---

maybe just clone the libuv api, eg: http://nikhilm.github.io/uvbook/filesystem.html

i think it's cross-platform across windows, GNU/Linux, MacOS?, Android

---

maybe mix the libuv api with a plan9 style thingee to unify the different file-like object APIs

---

some stream util functions:

https://github.com/htoooth/mississippi2

---

two utils libraries that i randomly found, dunno if any of them are any good (the first two have a bunch of github stars though):

http://pocoproject.org/ and http://pocoproject.org/docs/00100-GuidedTour.html ( https://github.com/pocoproject/poco )

https://github.com/waruqi/tbox https://github.com/Amaury/Ylib

and of course C++ Boost

---

"C++ template library of lock-free and fine-grained algorithms": http://libcds.sourceforge.net/

---

"the most useful data structures, such as strings, lists, trees, associative arrays, vectors, matrices, and sets, " -- Evolving a language in and for the real world: C++ 1991-2006

---

"Java's Calendar class is the poster child for APIs which are just miserable to use. You have to use all of their weird C like constants for access, months are freaking zero based, but weekdays are one based!" -- http://fantom.org/doc/docIntro/WhyFantom

---

" Some of this is normal cruft setting in, but much of it is a general philosophy in both Java and .NET API design. Both platforms tend toward APIs using a proliferation of small classes that are over abstracted and under powered. Fantom follows a very different philosophy - we believe in a very few, but powerful classes. A good example is the java.io package which contains over 60 classes and interfaces. To do anything useful requires three of four classes, and if you forget to use buffered streams, then performance goes to hell. And even with all of these classes, it is still a lot of work to do basic things like parse a file into lines of text. Fantom collapses most of the java.io functionality into four classes: File, Buf, InStream?, and OutStream?. The IO streams classes are buffered by default, support both binary and text, and have lots of conveniences built right in. "

"

Fantom was designed from the ground up to support functions as first class objects. "

---

Fantom claims to be "quite obsessive about providing all the key featuresrequired for a standard library, but with much less surfacearea than the APIs found in Java or .NET."

" Fantom provides a set of APIs which abstract away the Java and .NET APIs. We actually consider this one of Fantom's primary benefits, because it gives us a chance to develop a suite of system APIs that are elegant and easy to use compared to the Java and .NET counter parts...we are obsessed with making the Fantom APIs beautiful"

"Closures are a key feature of the language, and all the APIs are written to use functions and closures where appropriate.

---

libbsd ?

---

https://en.wikipedia.org/wiki/Newlib ?

---

'standard libraries' in https://en.wikipedia.org/wiki/Template:C_programming_language

---

https://glyph.twistedmatrix.com/2016/08/attrs.html

---

http://www.haskellforall.com/2016/07/list-transformer-beginner-friendly-listt.html

---

"

thinkpad20 34 days ago

parent [-]on: A founder's perspective on 4 years with Haskell

> The heavy and unnecessary usage of symbols, like, >>, 1=, >=>, <=<, and so on just adds cognitive overload and gives no inherent benefit but most of the Haskell library code is littered with it

This is an oft-repeated criticism of Haskell which I frankly find has no basis. Firstly, symbols are preferred for these kinds of functions precisely because of their ubiquity. Once you're familiar with them (which you almost certainly will quickly become, for the common ones like `>>=`, and `< * >`) they make the code easier to read, not harder, in general. Few would complain about having to write "<" to compare two numbers in most languages, rather than, say, "lessThan", because it's all over the place, and having a symbol for it makes it easier for a developer to read. The same is true for many common combinators in Haskell. There is no "cult-like insistence" on them; it's simply the case that many Haskell developers find them more pleasant to write than named functions. Honestly, the comparison to brainfuck is completely unfounded, and the references to cults and religious fetishes are IMO unnecessarily derisive.

Furthermore, I'd add that what makes the symbols seem hard is not the fact that they're symbols, but that the ideas that they're representing are challenging when coming from the world of imperative programming. Using a named function like "bind" rather than ">>=" or "apply" rather than "< * >" ..."

---

https://www.conj.io/

---

https://en.wikipedia.org/wiki/Space-cadet_keyboard#mediaviewer/File:Space-cadet.jpg

---

https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/asplos2011-drawbridge.pdf page 4

or

https://github.com/oscarlab/graphene/wiki/PAL-Host-ABI

---

Golang's bufio.NewReader?() and bufio.NewReader?().ReadString? and time.Now()

compare:

golang:

reader := bufio.NewReader?(os.Stdin) reader.ReadString?('\n')

C: int c; while((c = getc(stdin)) != EOF) { if( c == '\n' ) { gettimeofday((struct timeval *)timestamp, NULL); break; }

---

Golang's channels:

golang channel := make(chan time.Time)

compare to C's:

pthread_create(&listener, NULL, listen, &entered)

and golang:

... := <- channel

compared to C:

pthread_join(listener, NULL)

note also that pthread_join(listener, NULL) and pthread_join(listener, NULL) return an error status value that must be checked, whereas the Golang channel ops don't (i don't understand how that could be, though; surely it's possible to have 'too many channels'?). The Golang stuff is more concise.

---

" In fact, the synchronization classes in java.util.concurrent (locks, semaphores, countdown-latches and more) do not rely on OS-provided constructs, but are implemented directly in Java using CPU concurrency primitives like CAS combined with the ability to park and unpark fibers. Therefore, all we had to do to adapt these classes to work for fibers as well as threads was to replace all references to Thread with Strand, and every call to LockSupport?.park/unpark with calls to Strand.park/unpark. Quasar contains a few such ports from java.util.concurrent (the package’s source code is in the public domain) that work on strands and maintain the exact same API, so no code changes are required by clients of these classes. "

---

" With Java 8, we’ve been introduced to the new Stream API that allows applying aggregate operations like Filter, Sort or Map on streams of data. Another thing Streams allow are parallel operations on multicore machines when applying .parallelStream() – Splitting the work between threads using the Fork/Join framework introduced in Java 7. An evolution from the Java 6 java.util.concurrency library, where we met the ExecutorService? which creates and handles our worker thread pools.

Fork/Join is also built on top of the ExecuterService?, the main difference from a traditional thread pool is how they distribute the work between threads and thereby multicore machine support. With a simple ExecuterService? you’re in full control of the workload distribution between worker threads, determining the size of each task for the threads to handle. With Fork/Join on the other hand, there’s a work-stealing algorithm in place that abstracts workload handling between threads. "

---

---

http://www.1024cores.net/home/technologies

" The first thing to say is that there are two main categories of libraries and technologies. The first category is targeted at parallel computations (HPC), that is, it will help you to parallelize computations (like matrix multiplication, sorting, etc). OpenMP?, Cilk++, TBB, QuickThread?, Ct, PPL, .NET TPL, Java Fork/Join fall into this category.

The second category is targeted at general concurrency, that is, it will help to implement things like multi-threaded servers, rich client application, games, etc. TBB, QuickThread?, just::thread, PPL, AAL, AppCore? fall into this category. .NET and Java standard libraries also include some things that may be of help (like concurrent containers, synchronization primitives, thread pools, etc).

As you may notice, some libraries are mentioned in both categories. For example, Intel TBB contains some primitives that help with parallel computations (parallel algorithms and task scheduler), and some things that help with general concurrency (threads, synchronization primitives, concurrent containers, atomics).

Efficient and scalable parallel computations is a rather difficult field, it's easy to create a parallel program that executes slower than original single-threaded version (and the more cores you add the slower it executes). So, if you are not doing something extraordinary, you may consider using internally parallelized libraries like Intel MKL, Intel IPP, AMD ACML. They are not only internally parallelized, they are also highly optimized and will be updates for future architectures. So you only need to call a function for matrix multiplication, FFT, video stream decoding, image processing or whatever you need.

Subpages (6): Concurrency Kit (C) FastFlow? (C++) Intel TBB Just::Thread (C++) OpenMP? QuickThread? (C++/Fortran) "

---

http://www.1024cores.net/home/technologies/just-thread

---

in Python, you can pack together a bunch of reused optional arguments into a namedtuple and pass that along instead, but then it's cumbersome to construct one of these while inheriting the defaults, eg:

    disassemble_raw_bytecode_file(infile,outfile, dis_opts=dis_defs._replace(allow_unknown_opcodes=args.allow_unknown_opcodes))

it would be better to have a namedtuple with defaults.

---

http://stackoverflow.com/questions/29290359/existence-of-mutable-named-tuple-in-python

recordclass simplenamespace

---

http://requirejs.org/

also, commonjs

---

on python testing libs:

" At first I thought I would discover that one was far superior to all the rest. But I don’t think that’s the case.

I do think pytest is by far the coolest and most advanced. However, unittest keeps improving, and is no slouch. And although nose isn’t really in development as far as I can tell, lots of people still use it successfull " -- https://leanpub.com/pythontesting/read

---

js functional programming frameworks and libraries:

"React, Cycle.js, Redux, MobX?, RxJS? or Ramda"

---

https://msdnshared.blob.core.windows.net/media/2016/09/netstandard-apis.png

https://github.com/dotnet/standard/tree/master/docs/netstandard-20#composition

https://github.com/dotnet/standard/tree/master/netstandard/ref

---

" Some avenues for quality improvement:

    Provide stable, extensible test/bench frameworks.
    Provide more push-button CI setup, e.g. have cargo new set up Travis/Appveyor.
    Restart the API guidelines project.
    Use badges on crates.io to signal various quality metrics.
    Perform API reviews on important crates.

Some avenues for discoverability improvement:

    Adding categories to crates.io, making it possible to browse lists like "crates for parsing".
    More sophisticated ranking and/or curation.

A number of ideas along these lines were discussed in the Rust Platform thread. " -- [1]

---

Haskell98's 16 basic typeclasses:

https://www.haskell.org/onlinereport/basic.html#standard-classes

---

Elm's package approval process:

https://github.com/elm-lang/package.elm-lang.org http://wayback.archive.org/web/20161109235120/https://github.com/elm-lang/package.elm-lang.org

---

fixed-size tuple size limits

http://reasonablypolymorphic.com/blog/elm-is-wrong#fn1 opines that a size limit of 7 (Elm) is too small, but 63 (Haskell) is okay

---

https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/ argues that Python's curio is a better framework than Python's (stdlib) asyncio. I already took notes on this essay elsewhere.

---

mi100hael 10 days ago [-]

After using Akka-HTTP, I never want to write a HTTP service with anything else.

reply

---

mstijak 1 hour ago [-]

I find wrong that most frameworks do not include any component library. Even if there is a vibrant community, you end up with 30 dependencies which do not play well together.

I'm the author of a commercial framework for BIG applications [1]. Once you put everything on the table you can see which features should go into the framework and you end up with things like localization, date/number formatting, form validation, keyboard navigation, layouts, tooltips, routing, modals, etc. Once you have all that, you can build a coherent widget/charting library on top of it.

[1]: http://cx.codaxy.com/v/master/docs/intro/feature-list

reply

---

open, read, write, connect, sendto, recvfrom, execve

-- https://drawings.jvns.ca/syscalls/

---

basic functionality, library functions, and syscalls needed for a shell:

https://brennan.io/2015/01/16/write-a-shell-in-c/ https://news.ycombinator.com/item?id=13112589

also contains a list of some key system calls and shell builtins.

some of its contents:

and https://news.ycombinator.com/item?id=13112721 mentions:

---

" Intel Cilk Plus allows C/C++ operations to be applied to multiple array elements in parallel, and also provides a set of built-in functions that can be used to perform vectorized shifts, rotates, and reductions. Similar functionality exists in Fortran 90; Cilk Plus differs in that it never allocates temporary arrays, so memory usage is easier to predict. Elemental functionsEdit

In Cilk Plus, an elemental function is a regular function which can be invoked either on scalar arguments or on array elements in parallel. They are similar to the kernel functions of OpenCL?. "

---

from Python:

PEP 519: Adding a file system path protocol

File system paths have historically been represented as str or bytes objects. This has led to people who write code which operate on file system paths to assume that such objects are only one of those two types (an int representing a file descriptor does not count as that is not a file path). Unfortunately that assumption prevents alternative object representations of file system paths like pathlib from working with pre-existing code, including Python’s standard library.

---

some Python datetime efforts:

sametmax 16 hours ago [-]

I wish Kenneth would have contributed to an existed project for once.

Arrow and pendulum (my current favorite) have a very decent API. The later one is especially well tested for the numerous corner cases of date handling, which I doubt Kenneth got right on first try.

For request, a full rewrite made sense because urllib sucked so much and we had no good alternatives. But for date time, alternative exists and they are good. Do not split the open source effort, join forces!

reply

robochat 13 hours ago [-]

Right, there's arrow and pendulum and also http://delorean.readthedocs.io/en/latest/index.html plus the Datetime options offered by pandas and the numpy.datetime64 type. It gets to be pretty confusing particularly when you need to start transforming between the different types.

reply

BoppreH? 15 hours ago [-]

Awesome! Timekeeping is hard and I'm glad we now have one more tool do deal with it.

One thing that is bothering me is that when you ask for `maya.when('tomorrow')`, or give only a date, you get back a timestamp with millisecond precision, representing 00:00 of that day. I understand this simplifies the implementation, but shouldn't `tomorrow` be a range, from 00:00 to 23:59?

Treating imprecise dates as ranges would allow for stuff like

  1. Did this event happen "yesterday" according to the US/Eastern time zone? timestamp in maya.when('yesterday', to_timezone='US/Eastern')
  2. Get me all events that happened last Friday (UTC) [event for event in events if event.time in maya.when('2016-12-16')]

Maybe I'm being naive, and there's a reason why this won't work, but this seems the way most humans deal with time.

PS: it failed to install on Windows, so I opened an issue at https://github.com/kennethreitz/maya/issues/10

reply

Klathmon 11 hours ago [-]

Honestly I feel like it would be easier to just have the "precision" of a date/time be adjustable.

Just off the top of my head, ISO8601 is already in the right order, just letting users "leave off" anything that's not important and then having a library interpret those "partial dates" as a range internally so it's easy to check identity or if one date is "in" another.

reply

BoppreH? 11 hours ago [-]

That's exactly what I meant. Omitted parts should not be treated as zeroes, but as "any".

reply

jeffbr13 5 hours ago [-]

Python already contains separate date and time objects for this purpose[1][2]!

[1]: https://docs.python.org/3/library/datetime.html#date-objects [2]: https://docs.python.org/3/library/datetime.html#time-objects

reply

BoppreH? 4 hours ago [-]

I think that would only work for day long ranges. What if I want the events that happened in the last hour, or that are scheduled for May?

reply

jeffbr13 2 hours ago [-]

Combine pure dates and times with timedelta[1]? Python's multiple comparison expressions help here too.

For events in the last hour, the following expression should evaluate to True:

    (datetime.now() - timedelta(hours=1)) <= event_datetime 

Checking whether event_datetime is within May of the current year is a bit more involved, but you may not need to convert everything to a date (would have to check in an interpreter):

     date.today().replace(month=5, day=1) <= event_datetime.date() <= date.today().replace(month=5, day=31)

The point is that the language already has good support for sensible time operations, but it's parsing is weak. And there's Arrow for that[2]!

[1]: https://docs.python.org/3/library/datetime.html#timedelta-ob... [2]: http://arrow.readthedocs.io/en/latest/

reply

robochat 4 hours ago [-]

The pandas library has a period data type if you're looking for one.

reply

supergreg 9 hours ago [-]

Maybe `when` should be renamed or an alias to `at` and add an `in` method to make it more explicit.

reply

---

ianamartin 9 hours ago [-]

I think its fascinating that the community has no consensus about a datetime library.

A lot of Python is really solved. We don't argue about using requests (a not-coincidental example). If you're using Python, and you need to deal with http, you use requests. Everyone knows this.

There are basically 3 platforms for web frameworks. Flask, Pyramid, and Django. Maybe we're a little more dissolute than C# or Ruby folks, but that's pretty impressive considering how much we Python people like to roll our own.

The fact that there is real disagreement about this among ourselves about this particular issue says to me that this is more about the difficulty of the problem than it is anything else.

reply

NelsonMinar? 9 hours ago [-]

Related: the datetime library in pretty much every language is terrible. The only one I've ever used that I remember not actively hating was MomentJS?.

Python's history of time types was terrible, as well. Particularly the era when we just used tuples of length 8 or 9 that weren't timezone aware.

reply

masklinn 8 hours ago [-]

> The only one I've ever used that I remember not actively hating was MomentJS?.

Boy do we disagree. Between the mutable API, the fuzzy parsing, the lack of tz support and the yet-another-reinvention of date/time formatting DSL[0] moment was one of those things I'd rather have not had in my life.

[0] which, to add insult to injury, is really similar to but not quite compatible with the LDML's

reply

STRiDEX? 7 hours ago [-]

I've used timezones with momentjs. http://momentjs.com/timezone/ Its great. The parsing also has a strict mode http://momentjs.com/docs/#/parsing/string-format/

When did you last use it? I love working with momentjs.

reply

masklinn 4 hours ago [-]

> I've used timezones with momentjs. http://momentjs.com/timezone/ Its great. The parsing also has a strict mode http://momentjs.com/docs/#/parsing/string-format/

Yes, relatively recent options or completely separate projects allow doing these things. Do you know what happens to options when the default behaviour looks like it works? They don't get used, and the original garbage remains.

> I love working with momentjs.

And as I wrote earlier, boy do we disagree.

reply

bjacobel 8 hours ago [-]

Funny that JavaScript? would find community alignment on something (anything!) where Python can't. I guess that's a testament to the work of the Moment creators.

reply

niftich 8 hours ago [-]

It is. Datetime is an unpleasant problem domain, and Tim was active both on SO [1] and Github, arguably so much so that it was to the detriment of his health [2].

In the case of Moment, a little promotion went a very long way, and the community was eager to take what's given so they wouldn't have to think too much about datetime, and focus on debating how to arrange and design their applications instead.

Moment's design is a testament to "let's not think too hard about datetime", and I mean that both as a compliment and a critique.

[1] http://stackoverflow.com/users/272034/timrwood?tab=summary [2] https://news.ycombinator.com/item?id=12175369

reply

... people's complaints about Maya: ...

Also: >>> dt = maya.now() >>> dt.datetime() datetime.datetime(2016, 12, 18, 19, 24, 50, 212663, tzinfo=<UTC>)

    >>> dt.datetime('Europe/Budapest')
    datetime.datetime(2016, 12, 18, 20, 24, 50, 212663, tzinfo=<UTC>)

I would not use it...

jMyles 12 hours ago [-]

What's up buddy?

My only real question:

> rand_day = maya.when('2011-02-07', timezone='US/Eastern')

This returning an object representing a DateTime? on the 6th (in UTC time) strikes me as perhaps "not for humans."

If I just see that line casually, I think I expect to get a Date and for it to be the 7th.

It looks like, in order to get this (arguably expected) object, I need to take the resulting MayaDT? epoch and run its `datetime` method, passing naive=True?

And I also see that _tz can only ever be pytz.timezone('UTC') - is this the result of some belief that timezones are illusions or something? :-)

For a while, I have kinda thought that timezones foment a confused mental model of time and teamwork. I prefer to think in terms of the astronomy - it's not actually a different time anywhere else, it's just that the sun is at a different position relative to the rest of the earth (and thus, ones faraway teammates and loved ones).

Anyway, thanks for yet another set of interesting ideas. Hope you are well.

reply

---

https://github.com/nothings/single_file_libs https://github.com/clibs/clib/wiki/Packages https://ccodearchive.net/list.html https://github.com/duneroadrunner/SaferCPlusPlus

---

random library:

https://github.com/cgrand/macrovich

---

https://lambdaisland.com/episodes/clojure-seq-seqable

---

string formatting with attribute access is unsafe: http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

should provide a safe formatter (probably as the default):

anderskaseorg 2 days ago [-]

The proposed idea of relying on undocumented internals and blacklisting attribute names to securely sandbox formatting strings is _really_ _dangerous_. Never do that in production code! Language expansions could render your sandbox unsafe at any time.

You can write your own safe formatting engine in much less code.

    def safe_format(fmt, **args):
        return re.sub(r'\{([^{}]*)\}', lambda m: args.get(m.group(1)), fmt)
    
    safe_format('{foo} {bar}', foo='Hello', bar='world')  # Hello world

Add bells and whistles as desired.

reply

wfunction 2 days ago [-]

+1 I freaked out when I saw it. Blacklists are just asking to get hacked.

reply

tedunangst 1 day ago [-]

The first bell added is likely to be field access.

reply

cyphar 1 day ago [-]

Which immediately becomes a security risk because classes can overload __getattr__ and __getitem__. So now you're executing random code.

Of course, %s does the same thing (__str__) but at least %s doesn't take any arguments.

reply

---

" In From Higher-Order Functions to Libraries And Frameworks, we had a look at multirec, a recursive combinator.

function mapWith (fn) { return function * (iterable) { for (const element of iterable) { yield fn(element); } }; }

function multirec({ indivisible, value, divide, combine }) { return function myself (input) { if (indivisible(input)) { return value(input); } else { const parts = divide(input); const solutions = mapWith(myself)(parts);

      return combine(solutions);
    }
  }} "

---

http://nbviewer.jupyter.org/url/norvig.com/ipython/Advent%20of%20Code.ipynb#Day-0:-Getting-Ready

---

" > I'd also like to hear about "what makes functional programming useful" if you have a minute.

This is sort of a book-length topic and I'm on my phone, but a few points worth looking up are (Generalized) Algebraic Data Types, Typeclasses (in particular Functor, Foldable, Applicative, Traversable, Monad (in particular Maybe, Either, and State)), Higher Kinded Types, corecursion, the Y combinator. "

---

lists and nils in common lisp and clojure:

[2]

summary:

---

werkzeug flup some sort of git API lib Ethereum API libs

---

(->> (range 5 10) ;; (5 6 7 8 9) List (filter odd?) ;; (5 7 9) (map inc) ;; (6 8 10) (reduce +)) ;; 24 " -- from [3]

---

in clojure:

" Nested updates is also easy to do. Works for both maps and vectors.

(assoc-in {:a {:b {:c 1}}} [:a :b :c] 2) ;; ^__target ^__path ^__value

returns {
a {:b {:c 2}}}

(update-in {:a {:b {:c 1}}} [:a :b :c] inc) ;; ^__target ^__path ^__updating function

returns {
a {:b {:c 2}}} " -- from [4]

---

https://hexdocs.pm/elixir/Kernel.html

---

https://github.com/palatable/lambda

--- https://golang.org/pkg/

---

http://shopify.github.io/liquid/

---

https://www.sqlite.org/json1.html

https://news.ycombinator.com/item?id=13556517

" This is an extension to the query language that adds support for encoding/decoding within the context of a query:

    SELECT DISTINCT user.name
    FROM user, json_each(user.phone)
    WHERE json_each.value LIKE '704-%';

"

---

"the Postgres JSON support where you can create indexes based on the structure of the JSON"

---

from https://talks.golang.org/2017/state-of-go.slide#43 :

" Sorting

Exercise:

Given a slice of Person

var p []Person

Print the slice sorted by name, age, and SSN.

        sort.Sort(byName(p))
        sort.Sort(byAge(p))
        sort.Sort(bySSN(p))

Easy, right? Sorting

Well, you forgot about this part.

type byName []Person

func (b byName) Len() int { return len(b) } func (b byName) Less(i, j int) bool { return b[i].Name < b[j].Name } func (b byName) Swap(i, j int) { b[i], b[j] = b[j], b[i] }

type byAge []Person

func (b byAge) Len() int { return len(b) } func (b byAge) Less(i, j int) bool { return b[i].AgeYears? < b[j].AgeYears? } func (b byAge) Swap(i, j int) { b[i], b[j] = b[j], b[i] }

type bySSN []Person

func (b bySSN) Len() int { return len(b) } func (b bySSN) Less(i, j int) bool { return b[i].SSN < b[j].SSN } func (b bySSN) Swap(i, j int) { b[i], b[j] = b[j], b[i] }

sort.Slice

Since Go 1.8 you can simply write this:

        sort.Slice(p, func(i, j int) bool { return p[i].Name < p[j].Name })
        sort.Slice(p, func(i, j int) bool { return p[i].AgeYears < p[j].AgeYears })
        sort.Slice(p, func(i, j int) bool { return p[i].SSN < p[j].SSN })

Also new SliceStable? and SliceIsSorted?. "

---

https://github.com/golang/proposal/blob/master/design/12914-monotonic.md

---

rspeer 13 hours ago [-]

Here's a wart. Why is reading lines from a file so hard? It's one of the first things people are going to need to do in a programming language.

On top of handling errors (which I understand is necessary, and which the ? operator makes easier), it requires importing BufReader? and BufRead?, and wrapping a reference to a file handle in BufReader?.

Nobody is going to know how to do this unless they come across it in Rust By Example or on Stack Overflow. Shouldn't a standard library be able to abstract over fiddly details like this? Why is it my job to tell it how to buffer?

I say this as someone who is enthusiastic about Rust, but still learning.

reply

douche 13 hours ago [-]

That's a good point. It's slightly reminiscent of Haskell, where you have to start trying to understand the IO monad and do notation to do the most trivial real-world examples.

In other languages, you might do File.ReadAllLines?("foo.txt"), and bam, you're done.

reply

dripton 13 hours ago [-]

Unless foo.txt is too big, in which case, bam, out of memory.

reply

sametmax 32 minutes ago [-]

No, Python, ruby and such have an common interface for all lazy iteration.

In Python you can just do:

    with open('file', [mode, encoding]) as f:

To get an auto closing file handle and then choose:

This interface works for most IO, including files, socket, etc.

So you can choose an automatic lazy buffer, a manual buffer, load everything in memory, etc. And still have a lot of control.

I think rust should be some traits to expose such a common high level interface on top of the current way it deals with files, to easy simple operations. Just make sure the documentation states what you can do to go lower level.

reply

int_19h 6 hours ago [-]

In C# (from which the original example is), these days - and for like 6 years now - what you do is File.ReadLines?, and you get a lazy enumerator.

reply

---


Footnotes:

1. ,