|
a library is something you call, a framework calls you
|
# ? Sep 21, 2015 18:59 |
|
|
# ? Jun 11, 2024 00:19 |
|
I started making a webapp in Python without a framework by making it a series of services that don't even know about HTTP. It'll render templates, do DB access, sessions, logging in, user accounts, etc, but without HTTP. Plus I can unit test it fully without having to use special HTTP-aware tests. Then I can write a minimalist Flask wrapper for it and I don't even have to use any middleware. Specific bugs can be easily isolated to either the HTTP layer or the application layer. No more loving around with HTTP issues until it's completely necessary. It's not not-invented-here syndrome as much as it is my frustration with the way web apps tend to be designed tightly around an HTTP framework, even down to the project structure. It does not make for an elegantly designed app and it has lead to burn-out in the past when I get sick of dealing with whichever framework I am using and don't have to time to extract and reimplement whichever part of it is frustrating me. As far as I'm concerned, HTTP is not a platform on which to build an application, but a transport protocol, with which to transport hypertext. But this is a controversial and unpopular opinion. Feels like making a VB6 program and putting all your logic right in the buttons.
|
# ? Sep 21, 2015 19:25 |
|
Volte posted:I started making a webapp in Python without a framework by making it a series of services that don't even know about HTTP. It'll render templates, do DB access, sessions, logging in, user accounts, etc, but without HTTP.
|
# ? Sep 21, 2015 19:45 |
|
Volte posted:I started making a webapp in Python without a framework by making it a series of services that don't even know about HTTP. It'll render templates, do DB access, sessions, logging in, user accounts, etc, but without HTTP. Plus I can unit test it fully without having to use special HTTP-aware tests. Then I can write a minimalist Flask wrapper for it and I don't even have to use any middleware. Specific bugs can be easily isolated to either the HTTP layer or the application layer. No more loving around with HTTP issues until it's completely necessary. idk isn't the model view controller separation usually enough for this? like in ~~an ideal webapp~~ the model should never touch http, it's a controller thing
|
# ? Sep 21, 2015 19:51 |
|
i mean, i've written code that's definitely 'model layer' that acts as a http client, but yeah
|
# ? Sep 21, 2015 20:43 |
|
Even the MVC frameworks are still wrapped up in the GET/POST idioms of HTTP in parts. You can definitely write a service layer, but the HTTP layer often handles too much business stuff, like handling what user is logged in. That's got nothing to do with HTTP. I don't consider HTTP to be a fundamental part of a web app, it's only the entry point to the application. I'd put code into the HTTP layer for the same reason I'd put it into the main() function. I'm a fan of designing applications as libraries with thin entry points, and most web frameworks seem like one monolithic entry point. Even if you write everything in a service layer, the structure of the application is generally dominated by the underlying framework, and that framework is almost always specifically an HTTP framework. I dunno if it's a practical difference or just an icky feeling but every single time I try to design a web app like that it ends up feeling poorly designed after awhile, and I'm pretty sure it's because I can't achieve the separation of my entire app (even the underlying session/user/db stuff) into a library with a thin HTTP entry point. My code either has to build a redundant second layer on top of all that stuff (cookies, sessions, auth, etc) to abstract it out, or let my library talk about it directly, thus coupling my environment-agnostic business logic to an arbitrarily specific entrypoint. So why not just take that redundant second layer and make it the only layer (as a library), and then use the smallest subset of Flask possible to make it into an HTTP app? It achieves my goal at least, and mirrors the relatively common pattern of implementing client applications as libraries with thin entry points. My thing is basically just an experiment, and could end up unmanageable, but I think if I handle it right it will be more pleasant to deal with than a traditional web app tends to be. To my mind at least. Then again, I have the NIH "benefit" of only needing to implement the exact subset of features that I will ever need. edit: Basically the 'C' in MVC has nothing to do with HTTP, which is where it usually lives. I just want to make the C completely neutral and move the HTTP in front of the whole thing. You could make a Telnet frontend too if you want. Volte fucked around with this message at 21:32 on Sep 21, 2015 |
# ? Sep 21, 2015 21:24 |
|
use asp.net mvc
|
# ? Sep 21, 2015 22:49 |
|
Shaggar posted:use asp.net mvc
|
# ? Sep 21, 2015 22:51 |
|
AWWNAW posted:i like writing tests for poo poo when i know what the results should be but i have no idea how to implement I am not a good programmer but can this be done with a binary search tree
|
# ? Sep 21, 2015 23:14 |
|
ahmeni posted:I am not a good programmer but can this be done with a binary search tree yeah you can definitely represent the list/array as a binary tree, but that doesn't automatically solve the problem of balancing the "gap" between each sequence int and minimizing the number of sequence ints that have to be changed or does it, and i'm just an even worse programmer?
|
# ? Sep 21, 2015 23:36 |
|
i'm not sure if working with it as a tree would even make it easier? seems like it might make it harder to deal with in tree form than a linear representation because of the multi-level traversals you'd have to do to ensure proper gapping between the node values
|
# ? Sep 21, 2015 23:39 |
|
crazypenguin posted:frameworks, probably. was it tef who defined a framework as an application with the functionality removed the but the assumptions left in, or was he quoting someone, or am i totally misremembering e: found it raminasi fucked around with this message at 23:48 on Sep 21, 2015 |
# ? Sep 21, 2015 23:41 |
|
The underlying question is after whether you're after an accurate representation of the order when the int is modified at all times, or if you want the int to be representative of the ordering -- when an int is resized, you want all other ints to be modified to represent the current order.
|
# ? Sep 21, 2015 23:41 |
|
Shaggar posted:use asp.net mvc
|
# ? Sep 21, 2015 23:49 |
|
they don't have to be if you don't want and you can write your controllers w/out any http related stuff if you really want. then put any http related stuff in the http parts of the pipeline.
|
# ? Sep 21, 2015 23:52 |
|
sounds cool. I would use that if using .NET was in any way shape or form an option.
|
# ? Sep 21, 2015 23:54 |
|
MononcQc posted:The underlying question is after whether you're after an accurate representation of the order when the int is modified at all times, or if you want the int to be representative of the ordering -- when an int is resized, you want all other ints to be modified to represent the current order. i want the int to be representative of the ordering. these are "objects" that have an int property that specify how they should be ordered. whenever an object gets "moved" to a different position, i want to update that sequence int to reflect its proper place in the whole thingie. the catch is how to most efficiently maintain the gaps between each object's sequence values to ensure the minimum number of changes that have to be made to other objects in the sequence. if the sequence ints are consecutive (1,2,3,4,5) and you move the last item to the front of the list, then i imagine the following options 1. decrement the moved object's sequence (== 0), only requiring the moved object to be "touched" 2. swap the moved object's sequence with the one that replaced it positionally, requires two touches 3. gap the sequences with some arbitrary size so that if you have a list like (100,200,300) and you move the last item to the middle, you end up with (100,150,200) and you only have to touch one object #1 sucks cuz eventually you underflow or overflow #2 sucks for inserting new items without having to consult the whole list of thingies #3 seems like the best approach to me but you'd have to occasionally "rebalance" the gaps between neighboring objects cuz they'd eventually become consecutive numbers
|
# ? Sep 21, 2015 23:55 |
|
i know this has to be a solved problem but i can't find it on stack overflow, like maybe it'd be called Ol' Smitty's linear distribution rebalancing algorithm or something
|
# ? Sep 21, 2015 23:58 |
|
that seems like a weird problem and wouldn't just moving it in the first place involve lots of poo poo getting 'touched'?
|
# ? Sep 22, 2015 00:00 |
|
updating every single list index is O(n) anyway so not that bad. maybe people haven't bothered doing a faster one because how many times per second are you going to reorder your list of things because there's not even a case where you have to update every single list index because the worst case for moving one element is like O(n/2) e: because because because because
|
# ? Sep 22, 2015 00:01 |
|
yeah it's a weird problem and i already went with a different solution that sidesteps all this poo poo, but i still want to solve this stupid toy problem the whole point is minimizing the the # of objects that need to be "persisted" because their sequence number changed, it's not about bike shedding in-memory performance, it's about avoiding expensive serialization
|
# ? Sep 22, 2015 00:03 |
|
why would moving objects result in serialization? or are these things stored as text and you are deserializing them to get the sequence number and reserializing them after changing it because if so then lol
|
# ? Sep 22, 2015 00:04 |
|
this is roughly equivalent to knowing your position in the list, i.e. how many elements come before or after you. If you store it in the object, then each update requires O(n) changes (without the skip mechanism) but the value is retrieved in O(1) once you got the element. If you don't store the int, you can instead calculate it dynamically as you go through the list/array for retrieval. If your item retrieval is already O(N), then there's no additional cost (in the grand scheme of things) to doing it dynamically that way rather than storing it in each object individually. If you use a tree, you can change that retrieval / update to O(log N), but every insertion requires you to update the parent node to increment/decrement the count on each change. When searching the tree for a position, each inner-node has a a count of how many elements are to the left and right, and can add and subtract them. It also gives you a quick way to get a total by fronting the cost at insertion time.
|
# ? Sep 22, 2015 00:10 |
|
about how many objects are you dealing with here, and what size can the ints be? if you care about total changes and the moves are random, you can go a long way by just splitting the difference, maybe moving 1-2 neighbors. sometimes you won't be able to find space and you'll have to renumber everything, but you should be able to keep the average number of changes below 2. to keep it to a small number of changes for each move, in a situation where objects keep being placed in similar locations, this is my best effort: after every move of an object to position P, look at several random objects and how far away their neighbors are on each side. the objects with the most extra space on the side opposite P get scooted over MononcQc posted:this is roughly equivalent to knowing your position in the list, i.e. how many elements come before or after you. you can't guarantee anything to be O(log N) because at some point you run low on available IDs and every move approaches O(N)
|
# ? Sep 22, 2015 00:43 |
|
AWWNAW posted:2. swap the moved object's sequence with the one that replaced it positionally, requires two touches wait now I'm confused, how is that a valid option, doesn't that ruin the object you swapped with? you move the last object to be near the front, now the old object that's still supposed to be near the front has sequence number 77348
|
# ? Sep 22, 2015 00:48 |
|
Dylan16807 posted:I don't really see the similarity. the object with ID 100 doesn't care if it has 95 things before it or 2, it just wants to stay at 100 and never move Dylan16807 posted:you can't guarantee anything to be O(log N) because at some point you run low on available IDs and every move approaches O(N) You can if you use a dynamic scheme and all objects are stored in a tree. Then insertion is O(log N) and calculating the ID is reading the values in the tree
|
# ? Sep 22, 2015 00:54 |
|
MononcQc posted:The way I get it from the sentence "i want the int to be representative of the ordering." is that if you can just return the ordering, then the ids are fine. I guess we're looking at different problems. I'll wait for AWWNAW to clarify things
|
# ? Sep 22, 2015 01:08 |
|
Dylan16807 posted:about how many objects are you dealing with here, and what size can the ints be? yeah you smelling what i'm cooking
|
# ? Sep 22, 2015 01:18 |
|
Demo code:code:
code:
|
# ? Sep 22, 2015 02:46 |
|
thank, i am undeserving of your erlang let us end this terrible derail and discuss poo poo that isn't stupid
|
# ? Sep 22, 2015 03:20 |
|
comedyblissoption posted:Essential mutable state is inherent to the problem you are trying to solve and cannot be eliminated. i'm halfway through the paper but this premise seems flawed to me: quote:In the ideal world we are not concerned with performance, and our language and infrastructure provide all the general support we desire. It is against this background that we are going to examine state and control. First up, it would plainly be a lot more ideal if we could derive the formal requirements mechanically, then we could ignore the complexities of the specification phase in addition to ignoring the implementation phase! more critical flaw is to start by ruling performance out of the equation for no good reason at all. if the performance of computing the results is of no concern then the least complicated way to achieve this is to never produce any results at all... obviously even in the ideal world the informal requirements would have to include "and the system SHALL at all times show how many units of work it has completed and how many more there's still to go until completion" the result of these is an ideal computing platform so "powerful" and abstract that it needs to solve the halting problem before it can produce any actual results as Daniel J. Bernstein argues in The death of optimizing compilers, as computers evolve and become faster at performing some given task, the tasks that need to be performed evolve too. they involve processing larger amounts of data, or perhaps doing more involved computation. in the end performance has increased, the user got more done in the same amount of time and the complexity of the software went up. thus it seems complexity is essential to software because user requirements are essential complexity and those are bounded by the performance of the hardware running the software
|
# ? Sep 22, 2015 03:21 |
|
AWWNAW posted:the problem is minimizing the number of changes required. if all your sequence numbers converge to being consecutive then you have to change a bunch of objects. the hard part is just ensuring there are gaps between each object while minimizing the number of required changes I guess? Are there constraints on the int property? does it have a min/max value (that isn't just the max addressable value or something like that)? Do you need constant time random access? Does it matter which int properties I change, besides trying to minimize it? How big is this list anyways? how often do you perform swaps, property lookups, etc. etc.? you could use a balanced binary tree to partition the natural numbers recursively and keep the numbering invariant, which depending on how you implemented it could get you something like 1) swaps are always O(1) and property lookup is either O(1) or O(log N) depending on if you cache it or not. 2) findByIndex could be O(log N) if you store the left subtree size in your node. otherwise its O(N) 3) insertion is O(N) unless you don't cache the int property, in which case its O(log(N)). so yeah, you can get everything down to O(Log N) or trade off insertion for constant in property if you only do swaps. the choice is yours!
|
# ? Sep 22, 2015 03:48 |
|
congrats, you all passed the interview and i'm preparing offer letters right now
|
# ? Sep 22, 2015 04:00 |
|
i look forward to being asked this question during a future amazon interview
|
# ? Sep 22, 2015 04:05 |
|
even better dumb idea. if you're down with using a vector, just have the objects take a reference/pointer to the vector. then each object can compute its offset into the vector.
|
# ? Sep 22, 2015 04:22 |
|
Max Facetime posted:i'm halfway through the paper but this premise seems flawed to me: i think it's really difficult to separate performance from implementation their idea of this special formal requirements language resulting in executable code is a pipedream at this point imo the ideas on managing complexity by minimizing mutable state are good springboards though for approaching problems
|
# ? Sep 22, 2015 07:42 |
|
crazypenguin posted:frameworks, probably. you write code atop a library but inside a framework
|
# ? Sep 22, 2015 13:49 |
|
i guess the best distinction i can think of between framework and library is in a framework you're working in it, not with it.
|
# ? Sep 22, 2015 17:26 |
|
hey it's all code right. lovely code to link against with which to write more lovely code. why discriminate or delineate
|
# ? Sep 22, 2015 17:28 |
|
|
# ? Jun 11, 2024 00:19 |
|
comedyblissoption posted:that's why i said the solution kind of sucked their observation about the way source code is written and organized, how a programmer has to pick one execution order even for statements that have no dependencies between them, and then a compiler having to prove that no dependencies exist to be able to choose a better execution order for them that was spot on
|
# ? Sep 22, 2015 20:11 |