How to write a macro like dot(.) operator in hylang? - async-await

We have some async properties (using #property) and some usual ones. We have to use hy to check if one is async or not using asyncio.iscoroutine function. The problem is we have to use getattr and not . operator, since dot will call the property inner function. We want to change our hy code without breaking the DSL used in other projects, that is, we do not want to use string notation (double quotes) for attribute name and therefore we need to write some macro working just like . but internally calls getattr.
=> (defmacro attr [obj attr] `(getattr ~obj '~attr))
=> (attr 5 real)
Traceback (most recent call last):
File "stdin-5bbedde10a6366314d9be4bd343639582b4d0748", line 1, in <module>
(attr 5 real)
AttributeError: 'int' object has no attribute 'real'
=> (. 5 real)
5

It sounds like you're confused about the semantics of Python properties, which is understandable, since they're rather hairy. In Python (and thus also in Hy for the equivalent constructions), foo.x and getattr(foo, "x") are always equivalent, even if x is a property. To get a property method as an object instead of calling it, you need to retrieve the attribute for the class (type(x)) instead of an instance, and getattr with a string literal and . remain interchangeable. In this example, getattr(type(foo), 'bar').fset could also be written as type(foo).bar.fset.

I tried
(defmacro attr [obj attr]
`(getattr ~obj ~(str attr)))
(print (attr 5 real))
in the web interpreter and it prints 5.
I was unable to reproduce your issue in the web interpreter though. It must still be running an older version, because I had to install your exact version to do it. I suspect that the following breaking change announced for 1.0a2 accounts for the difference:
Hy model objects are no longer equal to ordinary Python values. For
example, (!= 1 '1). You can promote values to models with hy.as-model
before making such a check.
My version of attr does work on Hy 1.0a3. I checked. Try it.
Attributes in Python are stored in the object's .__dict__ using string keys. Since Hy's symbols are no longer equal to strings, the lookup of a string key using a symbol will always fail. Converting the symbol to a string first fixes it. My initial comment was correct. (And this step is unnecessary in Hissp because it lacks Hy's separate model types.)

Although the latter answer works, but I found out that the problem is getting the method behind the property and as #kodiologist wrote, getattr and dot are equivalent. SO I used fget and :
(iscoroutinefunction (.fget (. (type obj) ~attr)))

Related

Scheme names with * as suffix

There are some forms in the tradition of Scheme that are named the same as more primitive forms but with a * appended as a suffix.
Some examples
let*
define*
Now for these derived forms the explanation is that you get visibility of your previous bindings
in the later bindings kind of a letrec style but creating one id at a time instead of all at once (?).
Now this pattern extends thought to other forms and some packages have custom macros with the * symbol as a suffix (define-ratbag*). Is this some implicit convention of the Scheme tribe, is this documented somewhere?
There are several things that a * suffix might mean:
sequential scoping like let*, as opposed to independent scoping like let. Examples: with-syntax* is like with-syntax, but each right-hand side is in the scope of previous clauses.
sequential effect as opposed to independent effect. Examples: parameterize* is like parameterize, but each parameter's new value is evaluated with the previous parameters updated to their new values; with-handlers* is like with-handlers, but each exception handler is called in a context with the previous exception handlers installed.
like the other thing, but multiple times. Examples: remove* is like remove, but removes all occurrences of the given element; regexp-match* is like regexp-match, but finds all matches.
like the other thing, but the final argument acts like a rest-argument. Examples append*, list*: (append* vss) is equivalent to (apply append vss).
like the other thing, but accepts multiple arguments. Examples: hash-set* is like hash-set, but accepts multiple key-value pairs.
like the other thing, but just a bit different. Examples: write-bytes-avail* is like write-bytes-avail, except it never blocks; date* is like date except it adds nanosecond and time-zone-name fields; call-with-input-file* is like call-with-input-file except closes the input port on escapes. In this usage, you can read * as Scheme/Racket's version of a prime suffix.

How does fillStyle work in bs-webapi Canvas2d

I'm wondering how to create a and set a fill style using bs-webapi and Canvas2d interface in ReasonML.
I think the definition I might need is this:
let fillStyle = (ctx: t) =>
ctx |> fillStyle |> reifyStyle;
But I'm having trouble understanding it.
I have previously used this project as a source of examples, but I think the bs-webapi has changed since that project was authored. At least the following line modeled after the example:
Canvas2d.fillStyle(ctx, "rgba(0,255,255,255)");
gives me this error:
Error: This function has type
Webapi.Canvas.Canvas2d.t => (Webapi.Canvas.Canvas2d.style('a), 'a)
It is applied to too many arguments; maybe you forgot a `;'.
The function you want is setFillStyle:
Canvas2d.setFillStyle(ctx, String, "rgba(0,255,255,255)");
This was renamed from fillStyle long ago, because there was no getter back then and the convention is to name the getter fillStyle and the setter setFillStyle. At the same time it was made to support gradients and pattern.
The way setFillStyle now works is that the second argument determines the type of the third. If you pass String as the second argument, the third is required to be a string. If you pass Gradient it needs to be a gradient, which you can get from createLinearGradient or createRadialGradient. And lastly you can pass Pattern, which requires the third argument be a pattern obtained from createPattern.
In general, you should refer to the Canvas2d test file for usage examples.

Python 3 psutil, extracting pid and name values?

For Python 3.5 on Windows 7 64-bit and the psutil 5 library.
I'm confused as to how to properly access the name and pid information provided within each class 'psutil.Process' item returned by psutil.process_iter().
The following code returns a class 'generator' object:
import psutil
curProcesses = psutil.process_iter()
A simple loop outputs each class 'psutil.Process' object contained within that generator:
for eachProcess in curProcesses:
print(eachProcess)
OUTPUT:
psutil.Process(pid=0, name='System Idle Process')
psutil.Process(pid=4, name='System')
... and so on ...
Now here's where I'm getting confused.
IF I modify the previous loop as follows, THEN I'll get an integer pid and a string name.
for eachProcess in curProcesses:
# Observe the two different forms of access.
print(eachProcess.pid)
print(eachProcess.name())
OUTPUT:
0
System Idle Process
4
System
... and so on ...
The resulting integer and string are exactly what I want. However, after several experiments I can only get them IF:
eachProcess.pid is NOT followed by parentheses ala eachProcess.pid. (Adding parentheses produces a TypeError: 'int' object is not callable exception.)
eachProcess.name is followed by parentheses ala eachProcess.name(). (Removing the parentheses returns a bound method Process.name instead of the name as a string.)
Why do the two keyword-looking arguments pid and name behave differently? (I suspect I'm about to learn something very useful about Python 3 generator objects...)
There is not much to it really: pid is a read-only attribute (created with the #property decorator), and name() is a method, both of the Process class. Methods need parens to be called in order to return data, while attributes are accessed without them. This bit of documentation might be helpful. Also, if you find it helpful, you can see the difference in implementation between name() and pid.
As far as why pid is a read-only attribute of Process, while a method name() needs to be called in order to get the process name, I am not sure. In fact, pid appears to be the only read-only attrubute on the process class, while all other information about the process instance is retrieved through method calls. Personally it seems inconsistent/non-standard to do it this way, but I assume that there is a good reason for this choice. I assume the main reason is so the PID cannot be changed accidentally since it is a crucial component. If the PID were a method instead of a read-only attribute, then eachProcess.pid = 123 in your loop would change the method to the int 123, while the way it currently is, this attempted reassignment will raise an error instead, so that the PID is protected in a sense, while eachProcess.name = 'foo' will probably go by without raising an error.
Also, note that while they may look like keyword arguments in the way they appear in the string representations of Process class instances, name() and pid are not keyword arguments (although pid can be passed as a keyword argument when creating a Process instance, but that is not what is happening here).
I made pid a class attribute / property mainly for consistency with subprocess.Popen.pid and multiprocessing.Process.pid stdlib modules (also threading.Thread.ident comes to mind).
Also, it's something which does not require any calculation (contrarily from name(), cmdline() etc.) and it never changes, so something read-only made more sense to me at the time.
It's a property rather than a mere attribute just to error out in case the user tries to change/set it.

How does a loosely typed language know how to handle different data types?

I was working on a simple task yesterday, just needed to sum the values in a handful of dropdown menus to display in a textbox via Javascript. Unexpectedly, it was just building a string so instead of giving me the value 4 it gave me "1111". I understand what was happening; but I don't understand how.
With a loosely typed language like Javascript or PHP, how does the computer "know" what type to treat something as? If I just type everything as a var, how does it differentiate a string from an int from an object?
What the + operator will do in Javascript is determined at runtime, when both actual arguments (and their types) are known.
If the runtime sees that one of the arguments is a string, it will do string concatenation. Otherwise it will do numeric addition (if necessary coercing the arguments into numbers).
This logic is coded into the implementation of the + operator (or any other function like it). If you looked at it, you would see if typeof(a) === 'string' statements (or something very similar) in there.
If I just type everything as a var
Well, you don't type it at all. The variable has no type, but any actual value that ends up in that variable has a type, and code can inspect that.

Type mismatch when calling a function in qtp

I am using QTP 11.5 for automating a web application.I am trying to call an action in qtp through driverscript as below:
RFSTestPath = "D:\vf74\D Drive\RFS Automation\"
LoadAndRunAction RFStestPath & LogInApplication,"Action1",oneIteration
Inside the LogInApplication(Action1) am calling a login function as:
Call fncLogInApplication(strURL,strUsesrName,strPasssword)
Definition of fncLogInApplication is written in fncLogInApplication.vbs
When I associate the fncLogInApplication.vbs file to driverscript, am able to execute my code without any errors. But when I de-associate .vbs file from driverscript and associate it to LogInApplication test am getting "Type mismatch: 'fncLogInApplication'"
Can anyone help me in the association please. I want fncLogInApplication to be executed when I associate to LogInApplication not to the main driverscript.
Please comment back if you require any more info
There is only one set of associated libraries that is active at any one time: That is always the outermost test's one.
This means if test A calls test B, test B will be executed with the libraries loaded based upon test A´s associated libraries list, not B's.
This also means that if B depends on a library, and B associated this library, but is called from test A (which does not associated this library), then B will fail to call (locate) the function since the associated libraries of B are never loaded (only those from A are). (As would A, naturally.).
If you are still interested: "Type mismatch" is QTPs (or VBScript´s) poor way of telling you: "The function called is not known, so I bet you instead meant an array variable dereference, and the variable you specified is equal to empty, so it is not an array, and thus cannot be dereferenced as an array variable, which is what I call a 'type mismatch'."
This reasoning is valid, considering the syntax tree of VB/VBScript: Function calls and array variable dereferences cannot be formally differentiated. Syntactically, they are very similar, or identical in most cases. So be prepared to handle "Type mismatch" like the "Unknown function referenced" message that VB/VBScript never display when creating VBScript code.
You can, however, load the library you want in test B´s code (for example, using LoadFunctionLibrary), but this still allows A to call functions from that library once B loaded it and returned from A´s call. This, and all the possible variations of this procedure, however, have side-effects to aspects like debugging, forward references and visibility of global variables, so I would recommend against it.
Additional notes:
There is no good reason to use CALL. Just call the sub or function.
If you call a function and use the result it returns, you must include the arguments in parantheses.
If you call a sub (or a function, and don´t use the result it returns), you must not include the arguments in parantheses. If the sub or function accepts only one argument, it might look like you are allowed to put it in parantheses, but this is not true. In this case, the argument is simply treated like a term in parantheses.
The argument "bracketing" aspects just listed can create very nasty bugs, especially if the argument is byRef, also due (but not limited) to the fact that VBScripts unfortunately allows you to pass values for a byRef argument (where a variable parameter is expected), so it is generally a good idea to put paranthesis only where it belongs (i.e. where absolutely needed).

Resources