Re: syntax for code blocks
You know what I find rich about all of this? >>>[ ... ]> I'd like to change the syntax of my module 'codeblocks' to make it >>>more >>>[ ... ]> pythonic. Kiuhnm posted a thread to the group asking us to help him make it more Pythonic, but he has steadfastly refused every single piece of help he was offered because he feels his code is good enough after all. So why are we perpetuating it? ~Temia -- When on earth, do as the earthlings do. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 05/04/2012 05:12 AM, Kiuhnm wrote: >> Hand-wavy, no real example, doesn't make sense. > > Really? Then I don't know what would make sense to you. Speaking as as an observer here, I've read your blog post, and looked at your examples. They don't make sense to me either. They aren't real examples. They are abstract examples. They do not answer the questions, "what actual, real world python problems does this solve?" and "how is this better than a plain python solution?" For example, I've seen ruby code where blocks are used in a real-world way. Could you not put in something similar in your examples? Since you've written this code you must use it in everyday python coding. Show us what you've been doing with it. Also while some of your blog snippets are snippets, other code examples you provide purport to be complete examples, when in fact they are not. For example, about 45% of the way down your blog page you have a block of code that looks to be self-contained. It has "import logging" and "import random" at the top of it. Yet it cannot run as it's missing an import of your module. You haven't presented *any* good code or use cases. >>> >>> Says who? You and some others? Not enough. How many people do you need to tell you this before it's good enough? Doesn't matter how genius your code is if no one knows when or how to use it. > It's impossible to have a constructive discussion while you and others > feel that way. You're so biased that you don't even see how biased you are. Having followed the conversation somewhat, I can say that you have been given a fair hearing. People aren't just dissing on it because it's ruby. You are failing to listen to them just as much as you claim they are failing to listen to them. >>> The meaning is clear from the context. Not really. For one we're not Ruby programmers here, and like has been said, where is a real example of real code that's not just some abstract "hello this is block1, this is block 2" sort of thing? Providing non-block code to compare is important too. > Unfortunately, communication is a two-people thing. It's been clear from > the first post that your intention wasn't to understand what I'm proposing. > There are some things, like what I say about name-clashing, that you > should understand no matter how biased you are. > If you don't, you're just pretending or maybe you weren't listening at all. well there's my attempt. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Fri, May 4, 2012 at 9:12 PM, Kiuhnm wrote: > If I and my group of programmers devised a good and concise syntax and > semantics to describe some applicative domain, then we would want to > translate that into the language we use. > Unfortunately, Python doesn't let you do that. No, this is not unfortunate. Python does certain things and does them competently. If Python doesn't let you write what you want the way you want, then you do not want Python. This is not an insult to Python, nor is it a cop-out whereby the Python Cabal tells you to shut up and go away, you aren't doing things the Proper Way, you need to change your thinking to be more in line with Correct Syntax. It is simply a reflection of the nature of languages. If I want to write a massively-parallel program that can be divided across any number of computers around the world, Python isn't the best thing to use. If I want to write a MUD with efficient reloading of code on command, Python isn't the best thing to use. If I want to write a device driver, Python isn't the best thing to use. If I want to write a simple script that does exactly what it should and didn't take me long to write, then Python quite likely IS the best thing to use. But whatever you do, play to the strengths of the language you use, don't play to its weaknesses. Don't complain when C leaks the memory that you forgot to free(), don't bemoan LISP's extreme parenthesizing, don't fight the Python object model. You'll only hurt yourself. In any case, you know where to find Ruby any time you want it. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 5/4/2012 4:44, alex23 wrote: On May 4, 2:17 am, Kiuhnm wrote: On 5/3/2012 2:20, alex23 wrote: locals() is a dict. It's not injecting anything into func's scope other than a dict so there's not going to be any name clashes. If you don't want any of its content in your function's scope, just don't use that content. The clashing is *inside* the dictionary itself. It contains *all* local functions and variables. This is nonsense. locals() produces a dict of the local scope. I'm passing it into a function. Nothing in the local scope clashes, so the locals() dict has no "internal clashing". Nothing is injecting it into the function's local scope, so _there is no "internal clashing"_. To revise, your original "pythonic" example was, effectively: def a(): pass def b(): pass func_packet = {'a': a, 'b': b} func(arg, func_packet) My version was: def a(): pass def b(): pass func_packet = locals() func(arg, func_packet) Now, please explain how that produces name-clashes that your version does not. It doesn't always produce name-clashes but it may do so. Suppose that func takes some functions named fn1, fn2 and fn3. If you only define fn2 but you forget that you already defined somewhere before fn1, you inadvertently pass to func both fn1 and fn2. Even worse, if you write def a(): pass def b(): pass func(arg, locals()) and then you want to call func again with c() alone, you must write this: def c(): pass a = b = None func(arg, locals()) Moreover, think what happens if you add a function whose name is equal to that of a function accepted by func. That's what I call name-clashing. My solution avoids all these problems, promote encapsulation and let you program in a more functional way which is more concise that the OOP way, sometimes. That's not the same thing. If a function accepts some optional callbacks, and you call that function more than once, you will have problems. You'll need to redefine some callbacks and remove others. That's total lack of encapsulation. Hand-wavy, no real example, doesn't make sense. Really? Then I don't know what would make sense to you. You haven't presented *any* good code or use cases. Says who? You and some others? Not enough. So far, pretty much everyone who has tried to engage you on this subject on the list. I'm sorry we're not all ZOMGRUBYBLOCKS111 like the commenters on your project page. It's impossible to have a constructive discussion while you and others feel that way. You're so biased that you don't even see how biased you are. The meaning is clear from the context. Which is why pretty much every post in this thread mentioned finding it confusing? I would've come up with something even better if only Python wasn't so rigid. The inability for people to add 6 billion mini-DSLs to solve any stupid problem _is a good thing_. It makes Python consistent and predictable, and means I don't need to parse _the same syntax_ utterly different ways depending on the context. If I and my group of programmers devised a good and concise syntax and semantics to describe some applicative domain, then we would want to translate that into the language we use. Unfortunately, Python doesn't let you do that. I also think that uniformity is the death of creativity. What's worse, uniformity in language is also uniformity in thinking. As I said in some other posts, I think that Python is a good language, but as soon as you need to do something a little different or just differently, it's a pain to work with. Because that would reveal part of the implementation. Suppose you have a complex visitor. The OOP way is to subclass, while the FP way is to accept callbacks. Why the FP way? Because it's more concise. In any case, you don't want to reveal how the visitor walks the data structure or, better, the user doesn't need to know about it. Again, nothing concrete, just vague intimations of your way being better. Sigh. So define&use a different scope! Thankfully module level isn't the only one to play with. We can do OOP even in ASM, you know? ??? You can do whatever you want by hand: you can certainly define your functions inside another function or a class, but that's just more noise added to the mix. I'm sorry but it is still clear-as-mud what you're trying to show here. Can you show _one_ practical, real-world, non-toy example that solves a real problem in a way that Python cannot? I just did. It's just that you can't see it. "I don't understand this example, can you provide one." "I just did, you didn't understand it." Your rephrasing is quite wrong. You asked for a practical example and I said that I already showed you one. It's just that you can't see it (as practical). Okay, done with this now. Your tautologies and arrogance are not clarifying your position at all, and I really don't give a damn, so *plonk* I don't care if you don't read this post.
Re: syntax for code blocks
alex23 writes: > The examples here are a wonder to behold as well: > http://mtomassoli.wordpress.com/2012/04/20/code-blocks-in-python/ Wow. “What really happens is that rewrite rewrites the code, executes it and quits.” Please keep this far away from anything resembling Python. -- \ “If you go flying back through time and you see somebody else | `\ flying forward into the future, it's probably best to avoid eye | _o__) contact.” —Jack Handey | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On May 4, 1:47 pm, Steven D'Aprano wrote: > I too am uncomfortable about passing locals() to a function, but not > because of imaginary "name clashes". The problem as I see it is that this > will give the function access to things the function has no need for. And I would never use it in the real world. If anything, I'd rebind via the function parameters: def f(arg,fn1=None,fn2=None): pass f('arg', **locals()) This way, only the aspects of the local scope that the function explicitly asks for are provided. But: I would _only_ do this in a context I controlled. However, that would be the _same_ context in which the code blocks example would also be used. I think. I'm still waiting to see an example that is clear. I've never _ever_ found myself thinking "this code would be a LOT clearer if I didn't have to give it a name..." > Another problem is that even in implementations where you can't rebind > locals, the called function might mutate them instead. If any of the > content of locals() are mutable, you're giving the function the potential > to mutate them, whether it needs that power or not. This is true. But that would be the case with a provided dict too. I wasn't suggesting someone blindly throw locals into every function and hope for the best. I was merely stating that if you know that your function is only going to use certain values, it doesn't matter how many values you pass it, if it chooses to ignore them. > My argument is that this is equivalent to passing locals() as argument. > Your local scope contains some arbitrary number of name bindings. Only > some of them are actually used. Why pass all (say) 25 of them if the > function only needs access to (say) three? Flip it: I've set up a local scope that _only_ contains the functions I need. Why manually create a dict, repeating the name of each function as a key, when I can just use locals()? > To me, passing locals() as an > argument in this fashion is a code-smell: not necessary wrong or bad, but > a hint that something unusual and slightly worrying is going on, and you > should take a close look at it because there *may* be a problem. Or, conversely, I _know_ what I'm doing in the context of my own code and it's the most elegant way to write it. Frankly, I don't really care; I'm sick of this whole thread. We're all taking bullshit abstractions & toy examples and none of it is indicative of how anyone would really write code. > > So far, pretty much everyone who has tried to engage you on this subject > > on the list. I'm sorry we're not all ZOMGRUBYBLOCKS111 like the > > commenters on your project page. > > Goddamit, did I miss a post somewhere? What the hell is this project > people keep talking about? https://bitbucket.org/mtomassoli/codeblocks/ The examples here are a wonder to behold as well: http://mtomassoli.wordpress.com/2012/04/20/code-blocks-in-python/ -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Fri, May 4, 2012 at 12:44 PM, alex23 wrote: > On May 4, 2:17 am, Kiuhnm wrote: >> I would've come up with something even better if only Python wasn't so rigid. > > The inability for people to add 6 billion mini-DSLs to solve any > stupid problem _is a good thing_. It makes Python consistent and > predictable, and means I don't need to parse _the same syntax_ utterly > different ways depending on the context. Agreed. If a language can be everything, it is nothing. Python has value BECAUSE it is rigid. A while ago I played around with the idea of a language that let you define your own operators... did up a spec for how it could work. It is NOT an improvement over modern languages. http://rosuav.com/1/?id=683 ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Thu, 03 May 2012 19:44:57 -0700, alex23 wrote: [snip] > My version was: > > def a(): pass > def b(): pass > > func_packet = locals() > func(arg, func_packet) > > Now, please explain how that produces name-clashes that your version > does not. I too am uncomfortable about passing locals() to a function, but not because of imaginary "name clashes". The problem as I see it is that this will give the function access to things the function has no need for. While CPython doesn't allow the called function to rebind names in the local scope (except in the case where the local scope is also the global scope), that may not apply to all Python implementations. So code which works safely in CPython may break badly in some other implementation. Another problem is that even in implementations where you can't rebind locals, the called function might mutate them instead. If any of the content of locals() are mutable, you're giving the function the potential to mutate them, whether it needs that power or not. Let me put it this way... suppose you had a function with a signature like this: def spam(a, b, c, **kwargs): ... and you knew that spam() ignores keyword arguments that it doesn't need. Or at least is supposed to. Suppose you needed to make this call: spam(23, 42, ham=None, cheese="something") Would you do this instead? foo = ['some', 'list', 'of', 'things'] spam(23, 42, ham=None, cheese="something", aardvark=foo) on the basis that since aardvark will be ignored, it is perfectly safe to do so? No, of course not, that would be stupid. Perhaps spam() has a bug that will mutate the list even though it shouldn't touch it. More importantly, you cause difficulty to the reader, who wonders why you are passing this unused and unnecessary aardvark argument to the function. My argument is that this is equivalent to passing locals() as argument. Your local scope contains some arbitrary number of name bindings. Only some of them are actually used. Why pass all (say) 25 of them if the function only needs access to (say) three? To me, passing locals() as an argument in this fashion is a code-smell: not necessary wrong or bad, but a hint that something unusual and slightly worrying is going on, and you should take a close look at it because there *may* be a problem. > So far, pretty much everyone who has tried to engage you on this subject > on the list. I'm sorry we're not all ZOMGRUBYBLOCKS111 like the > commenters on your project page. Goddamit, did I miss a post somewhere? What the hell is this project people keep talking about? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On May 4, 2:17 am, Kiuhnm wrote: > On 5/3/2012 2:20, alex23 wrote: > > locals() is a dict. It's not injecting anything into func's scope > > other than a dict so there's not going to be any name clashes. If you > > don't want any of its content in your function's scope, just don't use > > that content. > > The clashing is *inside* the dictionary itself. It contains *all* local > functions and variables. This is nonsense. locals() produces a dict of the local scope. I'm passing it into a function. Nothing in the local scope clashes, so the locals() dict has no "internal clashing". Nothing is injecting it into the function's local scope, so _there is no "internal clashing"_. To revise, your original "pythonic" example was, effectively: def a(): pass def b(): pass func_packet = {'a': a, 'b': b} func(arg, func_packet) My version was: def a(): pass def b(): pass func_packet = locals() func(arg, func_packet) Now, please explain how that produces name-clashes that your version does not. > >> and how would you pass only some selected functions? > > > You wouldn't. You would just refer to the required functions in the > > dict _in the same way you would in both your "bad python" and code > > block versions. > > See above. This is more nonsense. So calling 'a' in your dict is fine, but calling a in the locals() returned dict isn't? > That's not the same thing. If a function accepts some optional > callbacks, and you call that function more than once, you will have > problems. You'll need to redefine some callbacks and remove others. > That's total lack of encapsulation. Hand-wavy, no real example, doesn't make sense. > > You haven't presented *any* good code or use cases. > > Says who? You and some others? Not enough. So far, pretty much everyone who has tried to engage you on this subject on the list. I'm sorry we're not all ZOMGRUBYBLOCKS111 like the commenters on your project page. > The meaning is clear from the context. Which is why pretty much every post in this thread mentioned finding it confusing? > I would've come up with something even better if only Python wasn't so rigid. The inability for people to add 6 billion mini-DSLs to solve any stupid problem _is a good thing_. It makes Python consistent and predictable, and means I don't need to parse _the same syntax_ utterly different ways depending on the context. > Because that would reveal part of the implementation. > Suppose you have a complex visitor. The OOP way is to subclass, while > the FP way is to accept callbacks. Why the FP way? Because it's more > concise. > In any case, you don't want to reveal how the visitor walks the data > structure or, better, the user doesn't need to know about it. Again, nothing concrete, just vague intimations of your way being better. > > So define& use a different scope! Thankfully module level isn't the > > only one to play with. > > We can do OOP even in ASM, you know? ??? > > I'm sorry but it is still clear-as-mud what you're trying to show > > here. Can you show _one_ practical, real-world, non-toy example that > > solves a real problem in a way that Python cannot? > > I just did. It's just that you can't see it. "I don't understand this example, can you provide one." "I just did, you didn't understand it." Okay, done with this now. Your tautologies and arrogance are not clarifying your position at all, and I really don't give a damn, so *plonk* -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Thu, May 3, 2012 at 10:17 AM, Kiuhnm wrote: > On 5/3/2012 2:20, alex23 wrote: >> >> On May 2, 8:52 pm, Kiuhnm wrote: func(some_args, locals()) >>> >>> >>> I think that's very bad. It wouldn't be safe either. What about name >>> clashing >> >> >> locals() is a dict. It's not injecting anything into func's scope >> other than a dict so there's not going to be any name clashes. If you >> don't want any of its content in your function's scope, just don't use >> that content. > > > The clashing is *inside* the dictionary itself. It contains *all* local > functions and variables. Since all locals within a frame must have different names (or else they would actually be the same local), they cannot clash with one another. >> Because under no circumstance does "with function_name as >> string_signature" _read_ in an understandable way. It's tortuous >> grammar that makes no sense as a context manager. You're asking people >> to be constantly aware that there are two completely separate meanings >> to 'with x as y'. > > > The meaning is clear from the context. I would've come up with something > even better if only Python wasn't so rigid. It's really not very clear. I think the biggest difficulty is that it effectively reverses the roles of the elements in the with statement. The usual meaning of: with func(): do_stuff is that func is called to set up a context, and then the block is executed within that context. The modified meaning is that the block is gathered up as a code object and then passed as an argument into func (despite that func *appears* to be called with no arguments), which may or may not do something with it. In the former, the emphasis is on the code block; func is effectively an adverb. In the latter, func describes the main action, and the code block is the adverb. For that reason, I think that this would really need a brand new syntax in order to gain any real acceptance, not just a complicated overload of an existing statement. For that you'll need to use a preprocessor or a compiler patch (although I'm not denying that the run-time module rewriting is a neat trick). -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
> if only Python wasn't so rigid. what. You realize you'd have a little more luck with Python if you weren't wielding it like a cudgel in the examples you've posted here, right? Because it looks like you're treating the language as everything it isn't and nothing it is this whole time. No wonder you're having trouble making your code Pythonic. Go with the flow. ~Temia -- When on earth, do as the earthlings do. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 5/3/2012 2:20, alex23 wrote: On May 2, 8:52 pm, Kiuhnm wrote: func(some_args, locals()) I think that's very bad. It wouldn't be safe either. What about name clashing locals() is a dict. It's not injecting anything into func's scope other than a dict so there's not going to be any name clashes. If you don't want any of its content in your function's scope, just don't use that content. The clashing is *inside* the dictionary itself. It contains *all* local functions and variables. and how would you pass only some selected functions? You wouldn't. You would just refer to the required functions in the dict _in the same way you would in both your "bad python" and code block versions. See above. But as you're _passing them in by name_ why not just make it func(some_args) and pick them up out of the scope. Because that's not clean and maintainable. It's not different from using global variables. ...I'm beginning to suspect we're not engaging in the same conversation. This is very common in Python: from module1 import func1 def func2(args): pass def main(): # do something with func1 and func2 And I've never had problems maintaining code like this. I know _exactly_ the scope that the functions exist within because I added them to it. They're not _global_ because they're restricted to that specific scope. That's not the same thing. If a function accepts some optional callbacks, and you call that function more than once, you will have problems. You'll need to redefine some callbacks and remove others. That's total lack of encapsulation. _No one_ writes Python code like this. Presenting bad code as "pythonic" is a bit of a straw man. How can I present good code where there's no good way of doing that without my module or something equivalent? That was my point. You haven't presented *any* good code or use cases. Says who? You and some others? Not enough. This is unintuitive, to say the least. You're effectively replacing the common form of function definition with "with when_odd as 'n'", then using the surrounding context manager to limit the scope. What's so unintuitive about it? It's just "different". Because under no circumstance does "with function_name as string_signature" _read_ in an understandable way. It's tortuous grammar that makes no sense as a context manager. You're asking people to be constantly aware that there are two completely separate meanings to 'with x as y'. The meaning is clear from the context. I would've come up with something even better if only Python wasn't so rigid. Rather than overload one single function and push the complexity out to the caller, why not have multiple functions with obvious names about what they do that only take the data they need to act on? Because that would reveal part of the implementation. Suppose you have a complex visitor. The OOP way is to subclass, while the FP way is to accept callbacks. Why the FP way? Because it's more concise. In any case, you don't want to reveal how the visitor walks the data structure or, better, the user doesn't need to know about it. Then again, it's _really difficult_ to tell if something named 'func()' could have a real use like this. The problem is always the same. Those functions are defined at the module level so name clashing and many other problems are possible. So define& use a different scope! Thankfully module level isn't the only one to play with. We can do OOP even in ASM, you know? I remember a post on this ng when one would create a list of commands and then use that list as a switch table. My module let you do that very easily. The syntax is: with func()<< ':list': with 'arg': cmd_code with 'arg': cmd_code with '': cmd_code I'm sorry but it is still clear-as-mud what you're trying to show here. Can you show _one_ practical, real-world, non-toy example that solves a real problem in a way that Python cannot? I just did. It's just that you can't see it. Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 05/02/2012 10:26 PM, Michael Torrie wrote: > If you are experiencing name clashes you need to start dividing your > code up logically instead of keeping everything in the global namespace > of your module. I shouldn't have used the word "global" here as it's not actually global. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 05/02/2012 04:52 AM, Kiuhnm wrote: > The problem is always the same. Those functions are defined at the > module level so name clashing and many other problems are possible. Only functions defined at the module level are in fact in the module's namespace. For example, this works fine, and the definitions for one and two are only within their respective scopes: def other_part(): def one(): pass def two(): pass # do something with one and two def main(): def one(): pass def two(): pass # do something with one and two other_part() If you are experiencing name clashes you need to start dividing your code up logically instead of keeping everything in the global namespace of your module. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On May 2, 8:52 pm, Kiuhnm wrote: >> func(some_args, locals()) > > I think that's very bad. It wouldn't be safe either. What about name > clashing locals() is a dict. It's not injecting anything into func's scope other than a dict so there's not going to be any name clashes. If you don't want any of its content in your function's scope, just don't use that content. > and how would you pass only some selected functions? You wouldn't. You would just refer to the required functions in the dict _in the same way you would in both your "bad python" and code block versions. > > But as you're _passing them in by name_ why not just make it > > func(some_args) and pick them up out of the scope. > > Because that's not clean and maintainable. It's not different from using > global variables. ...I'm beginning to suspect we're not engaging in the same conversation. This is very common in Python: from module1 import func1 def func2(args): pass def main(): # do something with func1 and func2 And I've never had problems maintaining code like this. I know _exactly_ the scope that the functions exist within because I added them to it. They're not _global_ because they're restricted to that specific scope. > > _No one_ writes Python code like this. Presenting bad code as > > "pythonic" is a bit of a straw man. > > How can I present good code where there's no good way of doing that > without my module or something equivalent? > That was my point. You haven't presented *any* good code or use cases. > > This is unintuitive, to say the least. You're effectively replacing > > the common form of function definition with "with when_odd as 'n'", > > then using the surrounding context manager to limit the scope. > > What's so unintuitive about it? It's just "different". Because under no circumstance does "with function_name as string_signature" _read_ in an understandable way. It's tortuous grammar that makes no sense as a context manager. You're asking people to be constantly aware that there are two completely separate meanings to 'with x as y'. > > More importantly, _you're naming your "anonymous" code blocks_, I'm > > guessing so that func() can choose which ones to use. But if you're > > naming them, why not just use a function? > > I'm creating a dictionary, not naming my blocks just for the sake of it. > If you use a function, you end up with the solution that you called > 'bad' and non-pythonic. What I considered 'bad' was having a _single_ function that takes _multiple differing collections_ of named functions. Now you've moved the onus onto the caller to ensure that the function is provided what it needs in a specific context to do its thing. Rather than overload one single function and push the complexity out to the caller, why not have multiple functions with obvious names about what they do that only take the data they need to act on? Then again, it's _really difficult_ to tell if something named 'func()' could have a real use like this. > The problem is always the same. Those functions are defined at the > module level so name clashing and many other problems are possible. So define & use a different scope! Thankfully module level isn't the only one to play with. > I remember a post on this ng when one would create a list of commands > and then use that list as a switch table. My module let you do that very > easily. The syntax is: > > with func() << ':list': > with 'arg': > cmd_code > with 'arg': > cmd_code > with '': > cmd_code I'm sorry but it is still clear-as-mud what you're trying to show here. Can you show _one_ practical, real-world, non-toy example that solves a real problem in a way that Python cannot? -- http://mail.python.org/mailman/listinfo/python-list
RE: syntax for code blocks
Steven D'Aprano wrote: > >> Have you actually tried to use these code blocks of yours? I asked you > >> for a *working* example earlier, and you replied with examples that > >> failed with multiple NameErrors and no hint as to how to fix them. And > >> now you give an example that fails with SyntaxError. > > > > The examples I gave you work perfectly. > > Except they don't. > > Look, this isn't difficult. I asked for *working* examples, you gave > examples that give NameError. Some of those errors are easy to fix, e.g. > by importing the random and re modules. Some of them aren't. [snip] > > > It's clear that you don't even > > have the vaguest idea of how my module works or, otherwise, you'd know > > what you're doing wrong. > > Well duh. What module? Where do I find it? [snip part deux] > Whatever man. It's no skin off my nose. I've tried really hard to give > your proposal a fair go, but my care factor is rapidly running out if you > can't even be bothered to ensure your examples use legal Python syntax. I think the crucial link that was provided in another thread (and should have been included in a new thread on the same project) is http://mtomassoli.wordpress.com/2012/04/20/code-blocks-in-python/ The only example I see on that page (for running from module) that looks fully complete is: import codeblocks codeblocks.rewrite() def each(iterable, block): for e in iterable: block(e)# step into -> 6: with each(range(0, 10)) << 'x': print('element ' + str(x)) codeblocks.end_of_module() I have not tried this (or any) example. To me it seems like an overly complicated way to avoid creating a function def. Especially since it creates a function anyway (whether anonymous or named). Ramit Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology 712 Main Street | Houston, TX 77002 work phone: 713 - 216 - 5423 -- This email is confidential and subject to important disclaimers and conditions including on offers for the purchase or sale of securities, accuracy and completeness of information, viruses, confidentiality, legal privilege, and legal entity disclaimers, available at http://www.jpmorgan.com/pages/disclosures/email. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 02/05/2012 11:52, Kiuhnm wrote: I remember a post on this ng when one would create a list of commands and then use that list as a switch table. My module let you do that very easily. Kiuhnm I'll believe that when I see a reference to your code repository and the working example that others have already asked you to provide. -- Cheers. Mark Lawrence. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 5/2/2012 4:43, alex23 wrote: [Apologies in advance if this comes through twice] On May 2, 12:18 am, Kiuhnm wrote: "Most Pythonic" doesn't mean better, unfortunately. Nor does it mean "Kiuhnm prefers it". That goes without saying. For instance, assume that you want to write a function that accepts a dictionary of callbacks: func(some_args, callbacks) Pythonic way def when_odd(n): pass def when_prime(n): pass def before_check(): pass def after_check(): pass func(some_args, {'when_odd' : when_odd, 'when_prime' : when_prime, 'before_check' : before_check, 'after_check' : after_check}) When would you _ever_ define a function like this? Why are you passing in _named_ callbacks? Are you calling them by name? Then declare them in the function signature and rely on scoping. Does func() branch on existent keys? Then don't write code like that. At the very _least_, you could change the function call to: func(some_args, locals()) I think that's very bad. It wouldn't be safe either. What about name clashing and how would you pass only some selected functions? A second call would also need some cleaning up leading to some serious bugs. But as you're _passing them in by name_ why not just make it func(some_args) and pick them up out of the scope. Because that's not clean and maintainable. It's not different from using global variables. _No one_ writes Python code like this. Presenting bad code as "pythonic" is a bit of a straw man. How can I present good code where there's no good way of doing that without my module or something equivalent? That was my point. My way -- with func(some_args)<< ':dict': with when_odd as 'n': pass with when_prime as 'n': pass with before_check as '': pass with after_check as '': pass This is unintuitive, to say the least. You're effectively replacing the common form of function definition with "with when_odd as 'n'", then using the surrounding context manager to limit the scope. What's so unintuitive about it? It's just "different". More importantly, _you're naming your "anonymous" code blocks_, I'm guessing so that func() can choose which ones to use. But if you're naming them, why not just use a function? I'm creating a dictionary, not naming my blocks just for the sake of it. If you use a function, you end up with the solution that you called 'bad' and non-pythonic. I'm not entirely sure what your 'solution' offers over something like: class FOO(object): def __init__(self, fn): self.fn = fn def __enter__(self): return self.fn def __exit__(self, exc_type, exc_value, traceback): pass def func(x, before_check=None, after_check=None, when_odd=None, when_prime=None): pass with FOO(func) as f: def before_check(x): pass def after_check(x): pass def when_odd(x): pass def when_prime(x): pass f(1) The problem is always the same. Those functions are defined at the module level so name clashing and many other problems are possible. I remember a post on this ng when one would create a list of commands and then use that list as a switch table. My module let you do that very easily. The syntax is: with func() << ':list': with 'arg': cmd_code with 'arg': cmd_code with '': cmd_code Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On May 2, 12:18 am, Kiuhnm wrote: > "Most Pythonic" doesn't mean better, unfortunately. Neither does "Kiuhnm prefers it". > For instance, assume that you want to write a function that accepts a > dictionary of callbacks: > func(some_args, callbacks) > > Pythonic way > > > def when_odd(n): > pass > > def when_prime(n): > pass > > def before_check(): > pass > > def after_check(): > pass > > func(some_args, {'when_odd' : when_odd, > 'when_prime' : when_prime, > 'before_check' : before_check, > 'after_check' : after_check}) I'm sorry, when would you _ever_ do this? Why are you naming the functions twice? If you're passing in a dynamic set of functions, you'd _never know the names_, so my guess is you'd be iterating across it. If you _do_ know the names, why aren't you accessing them directly from the surrounding scope? Why aren't you including them in the function signature? Presenting bad examples as the Pythonic approach is a bit of a straw man. > My way > -- > > with func(some_args) << ':dict': > with when_odd as 'n': > pass > with when_prime as 'n': > pass > with before_check as '': > pass > with after_check as '': > pass I'm not sure what value your code blocks really provide. 1. You're effectively making "with when_odd as 'n'" mean "def when_odd(n)" 2. The 'with code_block_name as arguments' syntax is unintuitive, to say the least. Personally, I don't see what value it provides over something more explicit and standard: def func(x, before_check=None, after_check=None, when_odd=None, when_prime=None): pass with FOO(func, arg): def before_check(x): pass def after_check(x): pass def when_odd(x): pass def when_prime(x): pass I couldn't think of a name for the context manager...but I can't really think of a use for it either, so that seems fair. Actually, here's an even simpler example. In this case, the context manager doesn't have to interrogate the surrounding stack, but the function call itself is then explicit. class FOO(object): def __init__(self, fn): self.fn = fn def __enter__(self): return self.fn def __exit__(self, exc_type, exc_value, traceback): pass def func(x, before_check=None, after_check=None, when_odd=None, when_prime=None): pass with FOO(func) as f: def before_check(x): pass def after_check(x): pass def when_odd(x): pass def when_prime(x): pass f(1) But again _what do you gain from this_ other than an extra layer of unnecessary complexity. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On May 2, 12:43 pm, alex23 wrote: > I'm not entirely sure what your 'solution' offers over something like: > > class FOO(object): > def __init__(self, fn): > self.fn = fn > > def __enter__(self): > return self.fn > > def __exit__(self, exc_type, exc_value, traceback): > pass > > def func(x, before_check=None, after_check=None, when_odd=None, > when_prime=None): > pass Sorry, the func definition was meant to be: def func(x): # before_check, after_check, when_odd, when_prime used internally pass -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
[Apologies in advance if this comes through twice] On May 2, 12:18 am, Kiuhnm wrote: > "Most Pythonic" doesn't mean better, unfortunately. Nor does it mean "Kiuhnm prefers it". > For instance, assume that you want to write a function that accepts a > dictionary of callbacks: > func(some_args, callbacks) > > Pythonic way > > > def when_odd(n): > pass > > def when_prime(n): > pass > > def before_check(): > pass > > def after_check(): > pass > > func(some_args, {'when_odd' : when_odd, > 'when_prime' : when_prime, > 'before_check' : before_check, > 'after_check' : after_check}) When would you _ever_ define a function like this? Why are you passing in _named_ callbacks? Are you calling them by name? Then declare them in the function signature and rely on scoping. Does func() branch on existent keys? Then don't write code like that. At the very _least_, you could change the function call to: func(some_args, locals()) But as you're _passing them in by name_ why not just make it func(some_args) and pick them up out of the scope. _No one_ writes Python code like this. Presenting bad code as "pythonic" is a bit of a straw man. > My way > -- > > with func(some_args) << ':dict': > with when_odd as 'n': > pass > with when_prime as 'n': > pass > with before_check as '': > pass > with after_check as '': > pass This is unintuitive, to say the least. You're effectively replacing the common form of function definition with "with when_odd as 'n'", then using the surrounding context manager to limit the scope. More importantly, _you're naming your "anonymous" code blocks_, I'm guessing so that func() can choose which ones to use. But if you're naming them, why not just use a function? I'm not entirely sure what your 'solution' offers over something like: class FOO(object): def __init__(self, fn): self.fn = fn def __enter__(self): return self.fn def __exit__(self, exc_type, exc_value, traceback): pass def func(x, before_check=None, after_check=None, when_odd=None, when_prime=None): pass with FOO(func) as f: def before_check(x): pass def after_check(x): pass def when_odd(x): pass def when_prime(x): pass f(1) I called the context manager FOO because I couldn't think of a more appropriate name (contextscope?)...which is fair, as I can't think of a use for it either. If you want to automate the function call at the context manager exit, use something like this instead: class FOO(object): def __init__(self, fn, *args, **kwargs): self.fn = fn self.args = args self.kwargs = kwargs def __enter__(self): f = inspect.currentframe(1) self.scope_before = dict(f.f_locals) def __exit__(self, exc_type, exc_value, traceback): f = inspect.currentframe(1) scope_after = dict(f.f_locals) scope_context = set(scope_after) - set(self.scope_before) clocals = dict( [(k, scope_after[k]) for k in scope_context] ) self.kwargs.update(clocals) self.fn(*self.args, **self.kwargs) Maybe there is a compelling use case for code blocks but your toy example certainly isn't it. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Steven D'Aprano writes: > On Tue, 01 May 2012 19:07:58 +0200, Kiuhnm wrote: > > [entitled demands] > Believe it or not, the world does not revolve around you. We cannot > see what is in your head. If we ask for a WORKING EXAMPLE, you need to > give an example that includes EVERYTHING necessary to make it work. To forestall the next obvious but wrong response: no, this is not asking to see a massive complicated module dumped on us to pore over. The term missing from Steven's request is “minimal”. When presenting code for examination by others, we request that you present a complete, minimal, working example. Complete, so that we can take what you present and use it without guessing (likely incorrect guesses) what extra bits you did. Minimal, so that it contains *only* what is needed to demonstrate what you're trying to communicate. Yes, this probably means writing an example specifically to present to us; tough, the job falls to you if you want us to spend time on your issue. Working example: so that it actually does what you say it does, and we can verify that directly instead of speculating. > [...] > > Talking with you is a real pain. You're always partial in your > > opinions and this urge of yours to criticize other's work makes you > > look dumb or hopefully just lazy. Sometimes one side of a disagreement is just incorrect, and in those cases it's good to be partial in one's opinions and to criticise on the facts. You have entered may people's kill files, including mine, because of this inability to take criticism and this tendency to insult others baselessly. -- \ “Holy unrefillable prescriptions, Batman!” —Robin | `\ | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Tue, 01 May 2012 19:07:58 +0200, Kiuhnm wrote: > On 5/1/2012 17:11, Steven D'Aprano wrote: >>> My way >>> -- >>> >>> with func(some_args)<< ':dict': >>> with when_odd as 'n': >>> pass >>> with when_prime as 'n': >>> pass >> >> >> If you actually try that, you will see that it cannot work. You get: >> >> SyntaxError: can't assign to literal > > If you had read the module's docstring What module? > you would know that the public version uses > with when_odd << 'n': > pass Then why didn't you write that instead of something that gives SyntaxError? Not once, but EIGHT times. >> Have you actually tried to use these code blocks of yours? I asked you >> for a *working* example earlier, and you replied with examples that >> failed with multiple NameErrors and no hint as to how to fix them. And >> now you give an example that fails with SyntaxError. > > The examples I gave you work perfectly. Except they don't. Look, this isn't difficult. I asked for *working* examples, you gave examples that give NameError. Some of those errors are easy to fix, e.g. by importing the random and re modules. Some of them aren't. What are "ris", "repl", "_return", "sorted1", "key"? Where do they come from? What value should I give them to make your code work? Code doesn't magically start to work because you declare that it does. Anyone who takes the time to copy and paste your examples into a fresh Python interactive session will see that they don't. Here's one of your earlier examples. I've removed the unnecessary indentation and made the obvious import, so all it takes to run it is to copy it and paste into the Python prompt: import random numbers = [random.randint(1, 100) for i in range(30)] with sorted1 << sorted(numbers) << key << 'x': if x <= 50: _return(-x) else: _return(x) print(sorted1) If you try it, you get NameError: name 'sorted1' is not defined Fix that (how?) and you'll get another NameError, for 'key', and then a third, for '_return'. The syntax isn't very clear. If I had to guess what it does, I'd predict that maybe it sorts the random list and negates everything <= 50, e.g. given input [5, 99, 34, 88, 70, 2] it returns [-2, -5, -34, 70, 88, 99]. Obviously that's wrong. You say it should return [34, 5, 2, 70, 88, 99]. The Pythonic way to get that result is: import random numbers = [random.randint(1, 100) for i in range(30)] sorted(numbers, key=lambda x: -x if x <= 50 else x) which is much more straightforward and obvious than yours, and presumably much faster. So even if I could get your example working, it would not be very persuasive. > It's clear that you don't even > have the vaguest idea of how my module works or, otherwise, you'd know > what you're doing wrong. Well duh. What module? Where do I find it? How am I supposed to know what this module is when you haven't mentioned it? Believe it or not, the world does not revolve around you. We cannot see what is in your head. If we ask for a WORKING EXAMPLE, you need to give an example that includes EVERYTHING necessary to make it work. [...] > Talking with you is a real pain. You're always partial in your opinions > and this urge of yours to criticize other's work makes you look dumb or > hopefully just lazy. > I can't stand people like you who don't even have the decency of taking > the time to read the documentation of a project and just run their mouth > without any concern for facts. What project? You're the one who doesn't tell us what project we're supposed to use, and yet *I'm* the dumb one. This is comedy gold. > What I can't stand is that if I won't reply to your posts other lazy > people will believe the nonsense you say, but I'll have to live with > that because I've wasted enough time with you. Whatever man. It's no skin off my nose. I've tried really hard to give your proposal a fair go, but my care factor is rapidly running out if you can't even be bothered to ensure your examples use legal Python syntax. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Arnaud Delobelle wrote: On May 1, 2012 6:42 PM, "Jerry Hill" wrote: On Tue, May 1, 2012 at 1:07 PM, Kiuhnm wrote: If you had read the module's docstring you would know that the public version uses Are you aware that you've never posted a link to your module, nor it's docstrings? Are you also aware that your module is essentially unfindable on google? Certainly nothing on the first two pages of google results for 'python codeblocks' jumps out at me as a python module of that name. Perhaps you would have better luck if you either post the actual code you want people to critique, or posted a link to that code. He did post a link to a blog post describing his module and also a link to the actual code, on bitbucket IIRC. Actually, it was Ian Kelly that posted the blog reference. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
(sent from my phone) On May 1, 2012 6:42 PM, "Jerry Hill" wrote: > > On Tue, May 1, 2012 at 1:07 PM, Kiuhnm > wrote: > > If you had read the module's docstring you would know that the public > > version uses > > Are you aware that you've never posted a link to your module, nor it's > docstrings? Are you also aware that your module is essentially > unfindable on google? Certainly nothing on the first two pages of > google results for 'python codeblocks' jumps out at me as a python > module of that name. > > Perhaps you would have better luck if you either post the actual code > you want people to critique, or posted a link to that code. He did post a link to a blog post describing his module and also a link to the actual code, on bitbucket IIRC. Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Tue, May 1, 2012 at 1:07 PM, Kiuhnm wrote: > If you had read the module's docstring you would know that the public > version uses Are you aware that you've never posted a link to your module, nor it's docstrings? Are you also aware that your module is essentially unfindable on google? Certainly nothing on the first two pages of google results for 'python codeblocks' jumps out at me as a python module of that name. Perhaps you would have better luck if you either post the actual code you want people to critique, or posted a link to that code. -- Jerry -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Holy crap. Easy there, tiger. I understand you're frustrated, but the people here are trying to help, even if they've decided the means of helping is trying to explain why they feel your style of development isn't the best way to do things. You're going to wear out your welcome and not get any help at all if you go ballistic like that. :/ ~Temia -- When on earth, do as the earthlings do. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 5/1/2012 17:11, Steven D'Aprano wrote: My way -- with func(some_args)<< ':dict': with when_odd as 'n': pass with when_prime as 'n': pass If you actually try that, you will see that it cannot work. You get: SyntaxError: can't assign to literal If you had read the module's docstring you would know that the public version uses with when_odd << 'n': pass Have you actually tried to use these code blocks of yours? I asked you for a *working* example earlier, and you replied with examples that failed with multiple NameErrors and no hint as to how to fix them. And now you give an example that fails with SyntaxError. The examples I gave you work perfectly. It's clear that you don't even have the vaguest idea of how my module works or, otherwise, you'd know what you're doing wrong. Again, the module's docstring is your friend. You have a bug in one or more of those callbacks. Of course you do -- all non-trivial software has bugs. The question is, how are you going to find it? You can't unit-test the individual callbacks, because they don't exist in a form that can be tested. It's easy to come up with a solution, in fact those functions /do/ exist. You would know that if you had read the documentation or even my reply to a post of yours. So in this case, even though Python is slightly more verbose, and forces you to have the discipline of writing named functions ahead of time, this is actually a *good* thing because it encourages you to test them. If the callbacks are trivial functions, the Pythonic way is to use lambdas: func(some_args, {'when_odd': lambda n: n-1, 'when_prime': lambda n: n**2 - 1, ...}) although I would discourage that unless they are *really* trivial. But for callbacks of any complexity, they will need to be tested, otherwise how do you know they do what you want them to do? Your code blocks make unit testing of the callbacks impossible, and for that reason the Pythonic way is better. Talking with you is a real pain. You're always partial in your opinions and this urge of yours to criticize other's work makes you look dumb or hopefully just lazy. I can't stand people like you who don't even have the decency of taking the time to read the documentation of a project and just run their mouth without any concern for facts. What I can't stand is that if I won't reply to your posts other lazy people will believe the nonsense you say, but I'll have to live with that because I've wasted enough time with you. Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Wed, May 2, 2012 at 1:11 AM, Steven D'Aprano wrote: > So in this case, even though Python is slightly more verbose, and forces > you to have the discipline of writing named functions ahead of time, this > is actually a *good* thing because it encourages you to test them. > > If the callbacks are trivial functions, the Pythonic way is to use > lambdas: > > func(some_args, {'when_odd': lambda n: n-1, > 'when_prime': lambda n: n**2 - 1, > ...}) > > although I would discourage that unless they are *really* trivial. But > for callbacks of any complexity, they will need to be tested, otherwise > how do you know they do what you want them to do? Agreed. At work, I'm currently shoveling through a pile of Javascript code (about 500KB of it, one file) that largely looks like this: FOO={} FOO.bar={ init:function() { // ... initialization code }, quux:function(a,b) { //code for this function }, ajaxrequest:function() { var blah,blah; blah; return { foo:function() { blah; } }; }(), bleh:blah } It's all anonymous functions assigned to member variables. It's not easy to debug, and refactoring the code into something simpler is a weeks-long job. I know it is because I've already spent two on it. Oh, and notice how ajaxrequest isn't actually declaring a function at all, it's calling a function and using its return value? Important information like that is buried away instead of being in the function signature. Plus, to make matters worse, many of the function and object names are reused, so FOO.bar.ajaxrequest.foo() is completely different from FOO.something.else.foo() and both have just "foo:function()" as their signature. Write your code out of line unless it REALLY wants to be inline. Name the functions unless they're trivial. And yes, I did say that I would do them as in-line lambdas. I don't really see much value in the callback system you have here unless either they ARE that trivial, or it's patently obvious that they need to be functions, so I still stand by what I said. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Tue, 01 May 2012 16:18:03 +0200, Kiuhnm wrote: > "Most Pythonic" doesn't mean better, unfortunately. Perhaps. But this example is not one of those cases. > For instance, assume that you want to write a function that accepts a > dictionary of callbacks: >func(some_args, callbacks) > > Pythonic way > > > def when_odd(n): > pass [snip multiple function definitions] > func(some_args, {'when_odd' : when_odd, > 'when_prime' : when_prime, > 'before_check' : before_check, > 'after_check' : after_check}) > My way > -- > > with func(some_args) << ':dict': > with when_odd as 'n': > pass > with when_prime as 'n': > pass If you actually try that, you will see that it cannot work. You get: SyntaxError: can't assign to literal Have you actually tried to use these code blocks of yours? I asked you for a *working* example earlier, and you replied with examples that failed with multiple NameErrors and no hint as to how to fix them. And now you give an example that fails with SyntaxError. I'm reluctantly coming to the conclusion that these "code blocks" of yours simply do not work. > with before_check as '': > pass > with after_check as '': > pass You have a bug in one or more of those callbacks. Of course you do -- all non-trivial software has bugs. The question is, how are you going to find it? You can't unit-test the individual callbacks, because they don't exist in a form that can be tested. So in this case, even though Python is slightly more verbose, and forces you to have the discipline of writing named functions ahead of time, this is actually a *good* thing because it encourages you to test them. If the callbacks are trivial functions, the Pythonic way is to use lambdas: func(some_args, {'when_odd': lambda n: n-1, 'when_prime': lambda n: n**2 - 1, ...}) although I would discourage that unless they are *really* trivial. But for callbacks of any complexity, they will need to be tested, otherwise how do you know they do what you want them to do? Your code blocks make unit testing of the callbacks impossible, and for that reason the Pythonic way is better. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Wed, May 2, 2012 at 12:18 AM, Kiuhnm wrote: > "Most Pythonic" doesn't mean better, unfortunately. > > For instance, assume that you want to write a function that accepts a > dictionary of callbacks: > func(some_args, callbacks) > > Pythonic way > > > def when_odd(n): > pass > > def when_prime(n): > pass > > def before_check(): > pass > > def after_check(): > pass > > func(some_args, {'when_odd' : when_odd, > 'when_prime' : when_prime, > 'before_check' : before_check, > 'after_check' : after_check}) My way: func(some_args, {'when_odd': lambda: 1, 'when_prime': lambda: 2, 'before_check': lambda: 3, 'after_check': lambda: 4}) In a language where lambda isn't restricted to a single expression (eg Javascript, Pike), this works even better, but it's still plausible for many situations. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 5/1/2012 5:27, alex23 wrote: On Apr 30, 2:05 am, Peter Pearson wrote: Hey, guys, am I the only one here who can't even guess what this code does? When did Python become so obscure? Thankfully it hasn't. The most Pythonic way to pass around a code block is still to use a function. "Most Pythonic" doesn't mean better, unfortunately. For instance, assume that you want to write a function that accepts a dictionary of callbacks: func(some_args, callbacks) Pythonic way def when_odd(n): pass def when_prime(n): pass def before_check(): pass def after_check(): pass func(some_args, {'when_odd' : when_odd, 'when_prime' : when_prime, 'before_check' : before_check, 'after_check' : after_check}) def when_prime(n): pass def when_perfect(n): pass def before_reduction() pass def after_reduction(): pass func(some_args, {'when_prime' : when_prime, 'when_perfect' : when_perfect, 'before_reduction' : before_reduction, 'after_reduction' : after_reduction}) My way -- with func(some_args) << ':dict': with when_odd as 'n': pass with when_prime as 'n': pass with before_check as '': pass with after_check as '': pass with func(some_args) << ':dict': with when_prime as 'n': pass with when_perfect as 'n': pass with before_reduction as '': pass with after_reduction as '': pass Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
mwil...@the-wire.com writes: > Another take-away might be don't use boilerplate, but in the situation > I didn't see a simple way to avoid it. It seems we agree, then, that avoiding boilerplate code is preferable to writing bad boilerplate code. -- \ “Computer perspective on Moore's Law: Human effort becomes | `\ twice as expensive roughly every two years.” —anonymous | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: ctypes details was: Re: syntax for code blocks
Kiuhnm wrote: > Regarding ctypes, try this to convince yourself that there's no problem > in reusing BignumPtrType: > from ctypes import POINTER, c_int > assert POINTER(c_int) is POINTER(c_int) print ('POINTERs are shareable:', ctypes.POINTER (BignumType) is ctypes.POINTER (BignumType)) [ ... ] ('POINTERs are shareable:', True) Thanks. Mel. -- http://mail.python.org/mailman/listinfo/python-list
Re: ctypes details was: Re: syntax for code blocks
On 4/30/2012 17:42, mwil...@the-wire.com wrote: On 4/30/2012 17:02, Kiuhnm wrote: BignumTypePtr = ctypes.POINTER(BignumType) for op, op_word in ((libbnem.BN_add, libbnem.BN_add_word), (libbnem.BN_sub, libbnem.BN_sub_word)): op.argtypes = [BignumTypePtr] * 3 op_word.argtypes = [BignumTypePtr, ctypes.c_ulong] op.restype = op_word.restype = ctypes.c_int On second thought, BignumPtrType is probably the right name. (Way off the original topic, aren't we?) I haven't looked inside ctypes, and don't know what kind of thing ctypes.POINTER actually constructs. I was worried about falling into a [[a]]*3 kind of error -- unwittingly sharing a mutable object. I guess I really should look. Better off topic than uninterestingly in topic, IMHO. Regarding ctypes, try this to convince yourself that there's no problem in reusing BignumPtrType: from ctypes import POINTER, c_int assert POINTER(c_int) is POINTER(c_int) Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
ctypes details was: Re: syntax for code blocks
> On 4/30/2012 17:02, Kiuhnm wrote: >> BignumTypePtr = ctypes.POINTER(BignumType) >> >> for op, op_word in ((libbnem.BN_add, libbnem.BN_add_word), >> (libbnem.BN_sub, libbnem.BN_sub_word)): >> op.argtypes = [BignumTypePtr] * 3 >> op_word.argtypes = [BignumTypePtr, ctypes.c_ulong] >> op.restype = op_word.restype = ctypes.c_int > > On second thought, BignumPtrType is probably the right name. (Way off the original topic, aren't we?) I haven't looked inside ctypes, and don't know what kind of thing ctypes.POINTER actually constructs. I was worried about falling into a [[a]]*3 kind of error -- unwittingly sharing a mutable object. I guess I really should look. Mel. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 4/30/2012 17:02, Kiuhnm wrote: On 4/30/2012 16:17, mwil...@the-wire.com wrote: Ben Finney wrote: [ ... ] Even worse is the penchant for ‘foo .bar()’, the space obscures the fact that this is attribute access. I like the style sometimes when it helps to break the significantly different parts out of boilerplate: libbnem. BN_add .argtypes = [ctypes.POINTER (BignumType), ctypes.POINTER (BignumType), ctypes.POINTER (BignumType)] libbnem. BN_add .restype = ctypes.c_int libbnem. BN_add_word .argtypes = [ctypes.POINTER (BignumType), ctypes.c_ulong] libbnem. BN_add_word .restype = ctypes.c_int libbnem. BN_sub .argtypes = [ctypes.POINTER (BignumType), ctypes.POINTER (BignumType), ctypes.POINTER (BignumType)] libbnem. BN_sub .restype = ctypes.c_int libbnem. BN_sub_word .argtypes = [ctypes.POINTER (BignumType), ctypes.c_ulong] libbnem. BN_sub_word .restype = ctypes.c_int (there were a lot more in the original program where those came from.) Another take-away might be don't use boilerplate, but in the situation I didn't see a simple way to avoid it. Mel. BignumTypePtr = ctypes.POINTER(BignumType) for op, op_word in ((libbnem.BN_add, libbnem.BN_add_word), (libbnem.BN_sub, libbnem.BN_sub_word)): op.argtypes = [BignumTypePtr] * 3 op_word.argtypes = [BignumTypePtr, ctypes.c_ulong] op.restype = op_word.restype = ctypes.c_int On second thought, BignumPtrType is probably the right name. Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 4/30/2012 16:17, mwil...@the-wire.com wrote: Ben Finney wrote: [ ... ] Even worse is the penchant for ‘foo .bar()’, the space obscures the fact that this is attribute access. I like the style sometimes when it helps to break the significantly different parts out of boilerplate: libbnem. BN_add .argtypes = [ctypes.POINTER (BignumType), ctypes.POINTER (BignumType), ctypes.POINTER (BignumType)] libbnem. BN_add .restype = ctypes.c_int libbnem. BN_add_word .argtypes = [ctypes.POINTER (BignumType), ctypes.c_ulong] libbnem. BN_add_word .restype = ctypes.c_int libbnem. BN_sub .argtypes = [ctypes.POINTER (BignumType), ctypes.POINTER (BignumType), ctypes.POINTER (BignumType)] libbnem. BN_sub .restype = ctypes.c_int libbnem. BN_sub_word .argtypes = [ctypes.POINTER (BignumType), ctypes.c_ulong] libbnem. BN_sub_word .restype = ctypes.c_int (there were a lot more in the original program where those came from.) Another take-away might be don't use boilerplate, but in the situation I didn't see a simple way to avoid it. Mel. BignumTypePtr = ctypes.POINTER(BignumType) for op, op_word in ((libbnem.BN_add, libbnem.BN_add_word), (libbnem.BN_sub, libbnem.BN_sub_word)): op.argtypes = [BignumTypePtr] * 3 op_word.argtypes = [BignumTypePtr, ctypes.c_ulong] op.restype = op_word.restype = ctypes.c_int Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Ben Finney wrote: > [ ... ] Even worse is the > penchant for ‘foo .bar()’, the space obscures the fact that this is > attribute access. I like the style sometimes when it helps to break the significantly different parts out of boilerplate: libbnem. BN_add .argtypes = [ctypes.POINTER (BignumType), ctypes.POINTER (BignumType), ctypes.POINTER (BignumType)] libbnem. BN_add .restype = ctypes.c_int libbnem. BN_add_word .argtypes = [ctypes.POINTER (BignumType), ctypes.c_ulong] libbnem. BN_add_word .restype = ctypes.c_int libbnem. BN_sub .argtypes = [ctypes.POINTER (BignumType), ctypes.POINTER (BignumType), ctypes.POINTER (BignumType)] libbnem. BN_sub .restype = ctypes.c_int libbnem. BN_sub_word .argtypes = [ctypes.POINTER (BignumType), ctypes.c_ulong] libbnem. BN_sub_word .restype = ctypes.c_int (there were a lot more in the original program where those came from.) Another take-away might be don't use boilerplate, but in the situation I didn't see a simple way to avoid it. Mel. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Peter Pearson writes: > On Fri, 27 Apr 2012 13:24:35 +0200, Kiuhnm wrote: > > I'd like to change the syntax of my module 'codeblocks' to make it > > more pythonic. The “chained callable” style isn't very Pythonic, IMO. Even worse is the penchant for ‘foo .bar()’, the space obscures the fact that this is attribute access. Far from Pythonic, this seems to be an attempt to write some other language in Python code. > > Current Syntax: > > > > with res << func(arg1) << 'x, y': > > print(x, y) > > > > with res << func(arg1) << block_name << 'x, y': > > print(x, y) > > > > New Syntax: > > > > with res == func(arg1) .taking_block (x, y): > > print(x, y) > > > > with res == func(arg1) .taking_block (x, y) as block_name: > > print(x, y) > [snip] > > Hey, guys, am I the only one here who can't even guess what > this code does? When did Python become so obscure? No, you're not alone; I think that code is pretty poor at communicating the intent. AFAICT the above code is a proposal. I don't know who (other than the original poster) thinks it's any good. -- \ “I cannot be angry at God, in whom I do not believe.” —Simone | `\ De Beauvoir | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
29.04.12 19:05, Peter Pearson написав(ла): Hey, guys, am I the only one here who can't even guess what this code does? When did Python become so obscure? This isn't Python at all. It's Ruby. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
>> Current Syntax: >> >> with res << func(arg1) << 'x, y': >> print(x, y) >> >> with res << func(arg1) << block_name << 'x, y': >> print(x, y) >> >> New Syntax: >> >> with res == func(arg1) .taking_block (x, y): >> print(x, y) >> >> with res == func(arg1) .taking_block (x, y) as block_name: >> print(x, y) >[snip] > >Hey, guys, am I the only one here who can't even guess what >this code does? When did Python become so obscure? > >-- >To email me, substitute nowhere->spamcop, invalid->net. No, it's pretty impenetratable to me at a passing glance too. Not sure if I'd get anywhere handtracing it, though. ~Temia -- When on earth, do as the earthlings do. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Fri, 27 Apr 2012 13:24:35 +0200, Kiuhnm wrote: > I'd like to change the syntax of my module 'codeblocks' to make it more > pythonic. > > Current Syntax: > > with res << func(arg1) << 'x, y': > print(x, y) > > with res << func(arg1) << block_name << 'x, y': > print(x, y) > > New Syntax: > > with res == func(arg1) .taking_block (x, y): > print(x, y) > > with res == func(arg1) .taking_block (x, y) as block_name: > print(x, y) [snip] Hey, guys, am I the only one here who can't even guess what this code does? When did Python become so obscure? -- To email me, substitute nowhere->spamcop, invalid->net. -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
Kiuhnm wrote: I'd like to change the syntax of my module 'codeblocks' to make it more pythonic. Current Syntax: with res << func(arg1) << 'x, y': print(x, y) with res << func(arg1) << block_name << 'x, y': print(x, y) New Syntax: with res == func(arg1) .taking_block (x, y): print(x, y) with res == func(arg1) .taking_block (x, y) as block_name: print(x, y) The full form is equivalent to def anon_func(x, y): print(x, y) res = func(arg1, block_name = anon_func) Suggestions? I don't find either the current syntax nor the new syntax pythonic. ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 4/27/2012 18:07, Steven D'Aprano wrote: > On Fri, 27 Apr 2012 17:03:19 +0200, Kiuhnm wrote: > >> On 4/27/2012 16:09, Steven D'Aprano wrote: >>> On Fri, 27 Apr 2012 13:24:35 +0200, Kiuhnm wrote: >>> I'd like to change the syntax of my module 'codeblocks' to make it more pythonic. Current Syntax: with res<< func(arg1)<< 'x, y': print(x, y) with res<< func(arg1)<< block_name<< 'x, y': print(x, y) >>> >>> >>> I'm sorry, I don't see how this is a code block. Where is the code in >>> the block, and how can you pass it to another object to execute it? >> >> Maybe if you read the entire post... > > No, I read the entire post. It made no sense to me. Let me give one > example. You state: > > The full form is equivalent to > def anon_func(x, y): > print(x, y) > res = func(arg1, block_name = anon_func) > > but this doesn't mean anything to me. What's func? Where does it come > from? What's arg1? Why does something called block_NAME have a default > value of a function instead of a NAME? > > How about you give an actual working example of what you mean by a code > block and how you use it? The rewriting rules are the following, where X ---> Y means that X is rewritten as Y on the fly: 1) with res << func(args) << 'x, y': ---> def anon_func(x, y): res = func(args, anon_func) 2) with res << func(args) << block_name << 'x, y': ---> def anon_func(x, y): res = func(args, block_name = anon_func) That's all. func is some function which takes a function as a positional argument or as a keyword parameter neamed block_name. Some examples: 1) text = "Anyone should be able to read this message!" with ris << re.sub(r'(\w)(\w+)(\w)', string = text) << repl << 'm': inner_word = list(m.group(2)) random.shuffle(inner_word) _return (m.group(1) + "".join(inner_word) + m.group(3)) print(ris) which prints (something like): Aynnoe shluod be albe to read tihs msgseae! 2) numbers = [random.randint(1, 100) for i in range(30)] with sorted1 << sorted(numbers) << key << 'x': if x <= 50: _return(-x) else: _return(x) print(sorted1) which prints (something like): [50, 47, 46, 28, 28, 25, 24, 23, 21, 19, 16, 15, 14, 3, 52, 52, 53, 54, 58, 62, 63, 69, 70, 72, 74, 78, 84, 86, 90, 97] Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Fri, Apr 27, 2012 at 10:07 AM, Steven D'Aprano wrote: > How about you give an actual working example of what you mean by a code > block and how you use it? He wrote a full blog post about it last week: http://mtomassoli.wordpress.com/2012/04/20/code-blocks-in-python/ -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Fri, 27 Apr 2012 17:03:19 +0200, Kiuhnm wrote: > On 4/27/2012 16:09, Steven D'Aprano wrote: >> On Fri, 27 Apr 2012 13:24:35 +0200, Kiuhnm wrote: >> >>> I'd like to change the syntax of my module 'codeblocks' to make it >>> more pythonic. >>> >>> Current Syntax: >>> >>> with res << func(arg1) << 'x, y': >>> print(x, y) >>> >>> with res << func(arg1) << block_name << 'x, y': >>> print(x, y) >> >> >> I'm sorry, I don't see how this is a code block. Where is the code in >> the block, and how can you pass it to another object to execute it? > > Maybe if you read the entire post... No, I read the entire post. It made no sense to me. Let me give one example. You state: The full form is equivalent to def anon_func(x, y): print(x, y) res = func(arg1, block_name = anon_func) but this doesn't mean anything to me. What's func? Where does it come from? What's arg1? Why does something called block_NAME have a default value of a function instead of a NAME? How about you give an actual working example of what you mean by a code block and how you use it? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On 4/27/2012 16:09, Steven D'Aprano wrote: On Fri, 27 Apr 2012 13:24:35 +0200, Kiuhnm wrote: I'd like to change the syntax of my module 'codeblocks' to make it more pythonic. Current Syntax: with res << func(arg1) << 'x, y': print(x, y) with res << func(arg1) << block_name << 'x, y': print(x, y) I'm sorry, I don't see how this is a code block. Where is the code in the block, and how can you pass it to another object to execute it? Maybe if you read the entire post... Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list
Re: syntax for code blocks
On Fri, 27 Apr 2012 13:24:35 +0200, Kiuhnm wrote: > I'd like to change the syntax of my module 'codeblocks' to make it more > pythonic. > > Current Syntax: > > with res << func(arg1) << 'x, y': > print(x, y) > > with res << func(arg1) << block_name << 'x, y': > print(x, y) I'm sorry, I don't see how this is a code block. Where is the code in the block, and how can you pass it to another object to execute it? -- Steven -- http://mail.python.org/mailman/listinfo/python-list
syntax for code blocks
I'd like to change the syntax of my module 'codeblocks' to make it more pythonic. Current Syntax: with res << func(arg1) << 'x, y': print(x, y) with res << func(arg1) << block_name << 'x, y': print(x, y) New Syntax: with res == func(arg1) .taking_block (x, y): print(x, y) with res == func(arg1) .taking_block (x, y) as block_name: print(x, y) The full form is equivalent to def anon_func(x, y): print(x, y) res = func(arg1, block_name = anon_func) Suggestions? Kiuhnm -- http://mail.python.org/mailman/listinfo/python-list