Re: is the tools part of the test suite? currently tools/ddemangle doesn't compile on git master
On Saturday, 24 August 2013 at 03:20:42 UTC, Timothee Cour wrote: More often than not, the tools submodule ( https://github.com/D-Programming-Language/tools) will not build on git master. So I'm wondering whether it's even being tested before pushing commits. In short: no, unfortunately. David
alias this bug?
is this a bug? the call to join invalidates the name field of A: import std.array; import std.stdio; class A{ string name; this(string name){this.name=name;} alias name this; ~this(){ writeln(deleting); } } void main(){ auto a=[new A(`foo`)]; assert(a[0].length); writeln(1); auto temp=a.join( ); writeln(2); assert(!a[0].length); //a[0] is now empty! }
Re: pointers, null and Typedef...
On Friday, 23 August 2013 at 18:58:49 UTC, Paolo Invernizzi wrote: On Friday, 23 August 2013 at 12:17:08 UTC, John Colvin wrote: so, here's the situation: On 2.063.2 why not something like this: --- import std.typecons; alias T0 = Typedef!(void*, null, T0); alias T1 = Typedef!(void*, null, T1); static assert( ! is(T0 == T1)); struct A { T0 t; this(T0 init) { t = init; } } void foo(){ auto a = A(T0(null)); // auto b = A(T1(null)); Error! } --- Paolo It's const(void*) not just void* Unfortunately that breaks it.
What's the right way for doing this in D?
I liked to know which of this two methods is more common to you, A or B: Method A: import std.stdio; struct Vector2f { public: float x; float y; float dot(ref const Vector2f vec) const { return this.x * vec.x + this.y * vec.y; } } Method B: struct Vector2f { public: float x; float y; } float dot(ref const Vector2f lhs, ref const Vector2f rhs) { return lhs.x * rhs.x + lhs.y * rhs.y; } Until now I used Method A, but because of UFCS and the fact, that the dot product doesn't affect the object, I thought about which way would make more sense. I still like Method A but I'm curious what you think.
Re: What's the right way for doing this in D?
Namespace: I liked to know which of this two methods is more common to you, A or B: Both ways work. I usually prefer the first one because it's more DRY. I use external functions when I write functions that are meant to work on more different structs, or to reduce template bloat when a function works only on not templated values. Note that fields and methods are public on default in structs, so you don't need the public: tag. Bye, bearophile
Variant[Variant]
Hi Straight off, I should ask if Variant[Variant] is a feasable idea. I am writing a serialization module which is trying to make use of this. This is the function Variant unserialize(V:Variant)(ref const(char)[] str) { switch (str[0]) { case 'b': return Variant(unserialize!(bool)(str)); case 'i': return Variant(unserialize!(long)(str)); case 'f': return Variant(unserialize!(double)(str)); case 's': return Variant(unserialize!(string)(str)); case 'a': auto len = checkLengthTypeStart(str, 'a'); Variant[] va; foreach (i; 0..len) { va ~= unserialize!(Variant)(str); } return Variant(va); case 'o': auto leno = checkLengthTypeStart(str, 'o'); Variant[Variant] vaa; foreach (j; 0..leno) { auto v = unserialize!(Variant)(str); vaa[v] = unserialize!(Variant)(str); } return Variant(vaa); default: throw new Exception(format(Unknown serialize type '%c',str[0])); } } It seems to happily unserialize what I give into a Variant[Variant], but I can't get access to it. Here is the unittest code. const(char)[] tcd_ss = a2o3s1:ai1s1:bi2s1:ci3o3s1:di4s1:ei5s1:fi6; auto tcd_v = unserialize!(Variant)(tcd_ss); assert(tcd_v.type() == typeid(Variant[])); assert(tcd_v.length == 2); auto tcd1_v = tcd_v[0]; assert(tcd1_v.length == 3); assert(tcd1_v.type() == typeid(Variant[Variant])); auto va = Variant(a); auto tcd1a_v = tcd1_v[va]; // === Blows up here. By my reckoning, the key Variant(a) exists in tcd1_v. If not, shouldn't it give a Range Violation error? Instead it gives: std.variant.VariantException@std/variant.d(1231): Variant: attempting to use incompatible types immutable(char)[] and std.variant.VariantN!(24u).VariantN ./serialize(@trusted int std.variant.VariantN!(24u).VariantN.handler!(std.variant.VariantN!(24u).VariantN[std.variant.VariantN!(24u).VariantN]).handler(std.variant.VariantN!(24u).VariantN.OpID, ubyte[24]*, void*)+0x286) [0x811cd2a] ./serialize(@trusted std.variant.VariantN!(24u).VariantN std.variant.VariantN!(24u).VariantN.opIndex!(std.variant.VariantN!(24u).VariantN).opIndex(std.variant.VariantN!(24u).VariantN)+0x68) [0x811e654] ./serialize(void serialize.__unittestL257_1()+0x1839) [0x80d296d] ./serialize(void serialize.__modtest()+0x8) [0x8120b84] ./serialize(extern (C) bool core.runtime.runModuleUnitTests().int __foreachbody352(ref object.ModuleInfo*)+0x24) [0x812faac] ./serialize(int rt.minfo.moduleinfos_apply(scope int delegate(ref object.ModuleInfo*)).int __foreachbody541(ref rt.sections_linux.DSO)+0x37) [0x8128057] ./serialize(int rt.sections_linux.DSO.opApply(scope int delegate(ref rt.sections_linux.DSO))+0x2c) [0x81282ac] ./serialize(int rt.minfo.moduleinfos_apply(scope int delegate(ref object.ModuleInfo*))+0x14) [0x8128004] ./serialize(runModuleUnitTests+0x87) [0x812f9b7] ./serialize(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void runAll()+0x25) [0x81258e5] ./serialize(extern (C) int rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).void tryExec(scope void delegate())+0x18) [0x8125550] ./serialize(_d_run_main+0x121) [0x8125521] ./serialize(main+0x14) [0x81253f4] /lib/libc.so.6(__libc_start_main+0xf3) [0x429a5413] So I ask again, is Variant[Variant] too ambitious? If not ... help! Thanks in advance Regards Jason P.S. The full code can be found at http://jaypha.com.au/serialize.d if that helps.
Re: Template alias parameter: error: need 'this' for ...
On Friday, 23 August 2013 at 22:54:33 UTC, Jonathan M Davis wrote: Because without static it's a member variable, which means that you have to have a constructed object to access it (since it's part of the object). When you declare a variable in a class or struct static, then there's only one for the entire class or struct, so it can be accessed without an object. And when you do StructName.var or ClassName.var your accessing the variable via the struct or class rather than an object, so the variable must be static. - Jonathan M Davis But I declared the template static, not the variable. Is there a better way to pass a ‘member get’ expression to a template? I need this for calling ‘.offsetof’ on it, and for checking if the member's parent is a certain struct type.
Re: pointers, null and Typedef...
On Saturday, 24 August 2013 at 09:19:14 UTC, John Colvin wrote: On Friday, 23 August 2013 at 18:58:49 UTC, Paolo Invernizzi wrote: On Friday, 23 August 2013 at 12:17:08 UTC, John Colvin wrote: so, here's the situation: On 2.063.2 why not something like this: It's const(void*) not just void* Unfortunately that breaks it. Sorry John, you are right, naturally. - Paolo
templated isNaN
Someone can suggest me a convenient way to declare an 'isNaN' templated function that plays well with the 'standard.math.isNaN'? The target is to be able to define isNaN functions for my custom structures, and I want to keep the same name... --- import std.math; bool isNaN(T)(T t) if(is(T==string)){ return true; } // that is really necessary? What if I have my isNaN in different modules? Must duplicate? // bool isNaN(T)(T t) if(is(T:real)) { return std.math.isNaN(t); } void foo(){ bool b = isNaN(0.0); } /d471/f783.d(9): Error: template f783.isNaN does not match any function template declaration. Candidates are: /d471/f783.d(3):f783.isNaN(T)(T t) if (is(T == string)) /d471/f783.d(9): Error: template f783.isNaN(T)(T t) if (is(T == string)) cannot deduce template function from argument types !()(double) --- Thanks in advance! - Paolo Invernizzi
Wrapping an arbitrary class/struct API
Hello all, Suppose that I have a struct like e.g.: struct A { void foo(int n) { ... } void foo(Range)(Range r) { ... } int bar() { ... } int bar(double x) { ... } // ... and others ... } ... an I want to wrap it in another struct, B. If I do this manually it would be something like, struct B { private A a; void foo(int n) { return a.foo(n); } void foo(Range)(Range r) { return a.foo(r); } // ... etc ... } But suppose that I don't a priori know the list of functions (and function arguments) that need to be wrapped. How could I go about working this out, with a generic programming approach? More specifically, how could I work this out limited to a specific function of A (say, foo) ... ? Thanks best wishes, -- Joe
Re: Wrapping an arbitrary class/struct API
Whoops -- must have accidentally hit Reply there by accident, instead of clicking to send new mail. Didn't mean to hijack someone else's thread. :-(
Re: What's the right way for doing this in D?
On 8/24/13, Namespace rswhi...@googlemail.com wrote: Until now I used Method A, but because of UFCS and the fact, that the dot product doesn't affect the object, I thought about which way would make more sense. I still like Method A but I'm curious what you think. Note also that UFCS can introduce the function hijacking protection. For example, if you have: - module a; import b; struct A { } void test(A a) { } void main() { B b; b.test(); } - - module b; struct B { } void test(B b) { } - This will result in: a.d(10): Error: function a.test (A a) is not callable using argument types (B) I tend to use UFCS when I need the function to handle multiple types - e.g. a templated function that should be used with UFCS, or when I want to add UFCS syntax to a type which I have no control over (e.g. a Phobos or 3rd party library type). Otherwise if your function is only ever going to be used with a single type you might as well put it as a member function, unless you prefer otherwise (e.g. some people dislike indentation). Btw, I thought UFCS might disable using the 'super' syntax, but to my surprise it actually works: - class A { } void foo(A a) { } class B : A { void test() { super.foo(); // ok } } void main() { } - Pretty cool. Finally a note about the documentation. If you put your functions as member functions, the documentation becomes part of the aggregate type that they're members of. So it might make the documentation easier to read.
Re: Wrapping an arbitrary class/struct API
On Saturday, 24 August 2013 at 12:12:29 UTC, Joseph Rushton Wakeling wrote: Hi Joseph, I'm not really a D guru like others, but... ... an I want to wrap it in another struct, B. If I do this manually it would be something like, struct B { private A a; void foo(int n) { return a.foo(n); } void foo(Range)(Range r) { return a.foo(r); } // ... etc ... } But suppose that I don't a priori know the list of functions (and function arguments) that need to be wrapped. How could I go about working this out, with a generic programming approach? For this case I would use alias this, if you want to wrap every method... struct B { private A a; alias a this; } More specifically, how could I work this out limited to a specific function of A (say, foo) ... ? I think that you have to explicitly wrap them, maybe with a template to alleviate the copy/past... But maybe someone else can suggest a better solution! - Paolo Invernizzi
Re: templated isNaN
On 24/08/13 13:53, Paolo Invernizzi wrote: Someone can suggest me a convenient way to declare an 'isNaN' templated function that plays well with the 'standard.math.isNaN'? The target is to be able to define isNaN functions for my custom structures, and I want to keep the same name... Will this do? // import std.math, std.traits; bool isNaN(T)(T t) { static if (isNumeric!T) { return std.math.isNaN(t); } else { return true; } } unittest { assert(isNaN(NaN)); assert(!isNaN(0)); assert(!isNaN(0.0)); assert(isNaN(real.nan)); } // Since you were kind enough to answer my accidental response to your mail, I thought I'd try and return the favour ... ;-)
Re: templated isNaN
On 24/08/13 14:50, Joseph Rushton Wakeling wrote: static if (isNumeric!T) { return std.math.isNaN(t); } Note that the correct if () condition here depends on how you want your isNaN to behave in certain cases. Using isNumeric will mean isNaN('c') returns true. If you want isNaN to return false when passed a char type, use your if(is(T : real)) instead.
Re: Wrapping an arbitrary class/struct API
On Saturday, 24 August 2013 at 13:14:30 UTC, Joseph Rushton Wakeling wrote: Hello all, (This accidentally got posted as a reply to someone else's thread -- I'm reposting in order to make sure that thread doesn't get diverted.) Suppose that I have a struct like e.g.: struct A { void foo(int n) { ... } void foo(Range)(Range r) { ... } int bar() { ... } int bar(double x) { ... } // ... and others ... } ... an I want to wrap it in another struct, B. If I do this manually it would be something like, struct B { private A a; void foo(int n) { return a.foo(n); } void foo(Range)(Range r) { return a.foo(r); } // ... etc ... } But suppose that I don't a priori know the list of functions (and function arguments) that need to be wrapped. How could I go about working this out, with a generic programming approach, i.e. _without_ manually writing the individual cases? More specifically, how could I work this out limited to a specific function of A (say, foo) ... ? Thanks best wishes, -- Joe You might want to look at std.typecons.Proxy also, opDispatch is a very powerful tool for doing this sort of thing.
Re: Wrapping an arbitrary class/struct API
On 24/08/13 15:31, John Colvin wrote: You might want to look at std.typecons.Proxy also, opDispatch is a very powerful tool for doing this sort of thing. Thanks, I'll take a look :-)
Re: is the tools part of the test suite? currently tools/ddemangle doesn't compile on git master
On Sat, Aug 24, 2013 at 10:08:08AM +0200, David Nadlinger wrote: On Saturday, 24 August 2013 at 03:20:42 UTC, Timothee Cour wrote: More often than not, the tools submodule ( https://github.com/D-Programming-Language/tools) will not build on git master. So I'm wondering whether it's even being tested before pushing commits. In short: no, unfortunately. [...] Maybe it should be? It's a relatively small codebase, certainly nothing compared with dmd/druntime/phobos themselves. It wouldn't significantly hurt autotester performance to include it. T -- Tech-savvy: euphemism for nerdy.
Re: is the tools part of the test suite? currently tools/ddemangle doesn't compile on git master
Yes, and it would also help find buggy commits. Actually i'd argue other popular external d packages should be included in autotester (even if those wouldnt be blockers) On Aug 24, 2013 8:35 AM, H. S. Teoh hst...@quickfur.ath.cx wrote: On Sat, Aug 24, 2013 at 10:08:08AM +0200, David Nadlinger wrote: On Saturday, 24 August 2013 at 03:20:42 UTC, Timothee Cour wrote: More often than not, the tools submodule ( https://github.com/D-Programming-Language/tools) will not build on git master. So I'm wondering whether it's even being tested before pushing commits. In short: no, unfortunately. [...] Maybe it should be? It's a relatively small codebase, certainly nothing compared with dmd/druntime/phobos themselves. It wouldn't significantly hurt autotester performance to include it. T -- Tech-savvy: euphemism for nerdy.
Re: Using a range as a reference
do you mean refRange? http://dlang.org/phobos/std_range.html#.refRange
Re: Using a range as a reference
On Saturday, 24 August 2013 at 19:51:14 UTC, David wrote: do you mean refRange? http://dlang.org/phobos/std_range.html#.refRange Exactly, thank you! I've missed it as it is not listed in the tables of the range documentation, like the others, but only in the top-index... - Paolo Invernizzi
Re: Using a range as a reference
On Saturday, 24 August 2013 at 20:24:47 UTC, H. S. Teoh wrote: On Sat, Aug 24, 2013 at 10:02:56PM +0200, Paolo Invernizzi wrote: I've missed it as it is not listed in the tables of the range documentation, like the others, but only in the top-index... That would be a documentation bug. Please file a bug on http://d.puremagic.com/issues. Done: http://d.puremagic.com/issues/show_bug.cgi?id=10885 - Paolo Invernizzi
Re: std.algorithm's remove
On Sunday, 25 August 2013 at 02:24:30 UTC, maarten van damme wrote: hello, I'm a hobyist-programmer and around where I live there's a group of haskell fanatics. They posted solutions to a recent programming challenge which I find to be a bit ugly. For fun I wanted to implement it in d and a rough version (not correct yet, this was written/hacked in 5 minutes after reading the exercise) My rough version is posted here : http://dpaste.dzfl.pl/4b5a6578 if you look at the output, you'll see this particular line : omkom - komkom because of : kom momkom momkom - momkomm This is because of what remove from std.algorithm does. It not only returns a range with that element removed (as the name implies), it also modifies the original range. I assume this decision was made for efficiency purposes but that is one of the most ugliest things I have ever come across. At least c# forces the 'ref' in it's parameters so you know something's up. Is there any way I could've known this? (apart from reading the documentation on every single trivial function in the std library?) It was done that way intentionally because the purpose of remove is to remove from the source range. If you don't want to affect the source range use filter. I suspect you could trace remove's lineage back to C++ STL's remove which works similarly (but is significantly clunkier and harder to use).
Re: std.algorithm's remove
But remove doesn't truly remove from the source range because the length of the source range stays the same. It's return value is a modified copy of the source range. Filter doesn't really work right away because that would also remove duplicate elements while I only want to remove at a given index. It also makes for clunkier looking code and is counterintinuitive to come up with (I want to remove an element therefore I have to filter every element that isn't equal to that element from the source range...) And while I haven't worked in c++, even that appears to have remove_copy which is really what I want. I could use temporary variables and blow that neat line up in 3 lines which, while still readable, look redundant. I'm happy the d result is 3 times shorter then their haskell solution but not that the time spent was 5 minutes working and the rest of the time debugging. This as opposed to using racket where the time spent is 15 minutes but after that everything works great (while my racket experience is limited to playing around with it for 2 weeks now and then). 2013/8/25 Brad Anderson e...@gnuk.net On Sunday, 25 August 2013 at 02:24:30 UTC, maarten van damme wrote: hello, I'm a hobyist-programmer and around where I live there's a group of haskell fanatics. They posted solutions to a recent programming challenge which I find to be a bit ugly. For fun I wanted to implement it in d and a rough version (not correct yet, this was written/hacked in 5 minutes after reading the exercise) My rough version is posted here : http://dpaste.dzfl.pl/4b5a6578 if you look at the output, you'll see this particular line : omkom - komkom because of : kom momkom momkom - momkomm This is because of what remove from std.algorithm does. It not only returns a range with that element removed (as the name implies), it also modifies the original range. I assume this decision was made for efficiency purposes but that is one of the most ugliest things I have ever come across. At least c# forces the 'ref' in it's parameters so you know something's up. Is there any way I could've known this? (apart from reading the documentation on every single trivial function in the std library?) It was done that way intentionally because the purpose of remove is to remove from the source range. If you don't want to affect the source range use filter. I suspect you could trace remove's lineage back to C++ STL's remove which works similarly (but is significantly clunkier and harder to use).
Re: std.algorithm's remove
maarten van damme: Is there any way I could've known this? For me it was obvious even before reading the documentation that a remove function is meant to be in-place. But of course you could have different ideas. (apart from reading the documentation on every single trivial function in the std library?) Before using every function from the standard library you have to read its documentation, this is sure. You can not assume its behavour to be exactly the same you hope it to have. This is true for languages as Python too. Regarding your very quickly written D code, I suggest to decrease the indents size, put a space around operators, put immutable/const to everything that doesn't need to change (unless there are problems doing so). I also suggest to use UFCS chains, because they are more readable for this kind of code. Instead of the readln()[0..$-1] you could chomp, strip or do not retain newlines. Instead of array(splitter) it's simpler to just split. Instead of chain.length==0 it's better to use empty. The foreach usually doesn't need a type, and probably your for loop could written as a better foreach. I also suggest to add contracts to your code. Instead of returning a can't be solved, probably there are stronger typed solutions, like using an Algebraic or Nullable. Bye, bearophile
Re: std.algorithm's remove
Correction, I could really use remove to begin with, only have to dup the range. Still convinced that the remove behaviour is counterintuitive but I assume good reasons exist... 2013/8/25 maarten van damme maartenvd1...@gmail.com But remove doesn't truly remove from the source range because the length of the source range stays the same. It's return value is a modified copy of the source range. Filter doesn't really work right away because that would also remove duplicate elements while I only want to remove at a given index. It also makes for clunkier looking code and is counterintinuitive to come up with (I want to remove an element therefore I have to filter every element that isn't equal to that element from the source range...) And while I haven't worked in c++, even that appears to have remove_copy which is really what I want. I could use temporary variables and blow that neat line up in 3 lines which, while still readable, look redundant. I'm happy the d result is 3 times shorter then their haskell solution but not that the time spent was 5 minutes working and the rest of the time debugging. This as opposed to using racket where the time spent is 15 minutes but after that everything works great (while my racket experience is limited to playing around with it for 2 weeks now and then). 2013/8/25 Brad Anderson e...@gnuk.net On Sunday, 25 August 2013 at 02:24:30 UTC, maarten van damme wrote: hello, I'm a hobyist-programmer and around where I live there's a group of haskell fanatics. They posted solutions to a recent programming challenge which I find to be a bit ugly. For fun I wanted to implement it in d and a rough version (not correct yet, this was written/hacked in 5 minutes after reading the exercise) My rough version is posted here : http://dpaste.dzfl.pl/4b5a6578 if you look at the output, you'll see this particular line : omkom - komkom because of : kom momkom momkom - momkomm This is because of what remove from std.algorithm does. It not only returns a range with that element removed (as the name implies), it also modifies the original range. I assume this decision was made for efficiency purposes but that is one of the most ugliest things I have ever come across. At least c# forces the 'ref' in it's parameters so you know something's up. Is there any way I could've known this? (apart from reading the documentation on every single trivial function in the std library?) It was done that way intentionally because the purpose of remove is to remove from the source range. If you don't want to affect the source range use filter. I suspect you could trace remove's lineage back to C++ STL's remove which works similarly (but is significantly clunkier and harder to use).
Re: std.algorithm's remove
maarten van damme: But remove doesn't truly remove from the source range because the length of the source range stays the same. It's return value is a modified copy of the source range. Filter doesn't really work right away because that would also remove duplicate elements while I only want to remove at a given index. It also makes for clunkier looking code and is counterintinuitive to come up with (I want to remove an element therefore I have to filter every element that isn't equal to that element from the source range...) And while I haven't worked in c++, even that appears to have remove_copy which is really what I want. I agree that the design of std.algorithm.remove is bug prone. The compiler doesn't verify that you are using its result! I have also filed several bugs regarding the implementation of std.algorithm.remove. In the end your complaints are real. You can't expect Phobos to be perfect, but people work to fix it. Fixing such problems future D users will not find your problem. So I suggest you to think well about what your problem is, what you don't like on this, and then write a enhancement request for Phobos. Even if std.algorithm.remove can't be fixed, people can add a new function with a safer/more handy behavour. Bye, bearophile
Re: std.algorithm's remove
I'm not sure if it really is my place to criticize design decisions of a language written by people that devoted their career to computer science while I have only read some books out of boredom :) 2013/8/25 bearophile bearophileh...@lycos.com maarten van damme: But remove doesn't truly remove from the source range because the length of the source range stays the same. It's return value is a modified copy of the source range. Filter doesn't really work right away because that would also remove duplicate elements while I only want to remove at a given index. It also makes for clunkier looking code and is counterintinuitive to come up with (I want to remove an element therefore I have to filter every element that isn't equal to that element from the source range...) And while I haven't worked in c++, even that appears to have remove_copy which is really what I want. I agree that the design of std.algorithm.remove is bug prone. The compiler doesn't verify that you are using its result! I have also filed several bugs regarding the implementation of std.algorithm.remove. In the end your complaints are real. You can't expect Phobos to be perfect, but people work to fix it. Fixing such problems future D users will not find your problem. So I suggest you to think well about what your problem is, what you don't like on this, and then write a enhancement request for Phobos. Even if std.algorithm.remove can't be fixed, people can add a new function with a safer/more handy behavour. Bye, bearophile
Error building doc's chm
Not sure if I'm doing something wrong here, but using DMD 2.063.2 on Win, trying to build the CHM docs like this: git clone https://github.com/D-Programming-Language/druntime.git git clone https://github.com/D-Programming-Language/phobos.git git clone https://github.com/D-Programming-Language/dlang.org.git cd druntime git checkout v2.063.2 make doc DOCSRC=../dlang.org DOCDIR=../dlang.org/phobos -f win32.mak cd ../phobos git checkout v2.063.2 make html DOCSRC=../dlang.org DOC=../dlang.org/phobos -f win32.mak cd ../dlang.org git checkout v2.063.2 make -f win32.mak make chm -f win32.mak Results in a bunch of these warnings: Warning: Page not found in navigation Followed by these errors: Invalid URL: .\function.html#parameters out of: #parameters Broken anchor link to keyword in to function.html#parameters as function parameter: Functions Invalid URL: .\function.html#parameters out of: #parameters Broken anchor link to keyword inout/tt ''(deprecated, use ttref to function.html#parameters as function parameter: Functions Invalid URL: .\function.html#parameters out of: #parameters Broken anchor link to keyword lazy to function.html#parameters as function parameter: Functions Invalid URL: .\function.html#parameters out of: #parameters Broken anchor link to keyword out to function.html#parameters as function parameter: Functions Invalid URL: .\function.html#parameters out of: #parameters Broken anchor link to keyword ref to function.html#parameters as function parameter: Functions