I am a developer at Microsoft and work in the .NET Common Language Runtime (CLR) team. For the last 4 years I have been working on virtual machine technologies on a variety of form factors including desktops (Windows, Linux), tablets (Win8), gaming-consoles (Xbox 360), mobile devices (Windows Phone 7, Windows CE, Symbian).I have worked on various core pieces of the runtime including Garbage Collector, memory manager, platform abstraction layer, runtime-performance, etc.Before working on .NET I worked on Visual Studio Team Foundation Server, Visual Studio Team System, Adobe Framemaker, Adobe Acrobat, Texas Instrument's Code Composer Studio.
...they both use threads and fibers :)
Most people are aware of processes and threads. Windows offers an even finer granularity over execution. This is called Fiber. To quote MSDN
A fiber is a unit of execution that must be manually scheduled by the application. Fibers run in the context of the threads that schedule them.
The obvious question that should come to managed code developers is whether .NET supports Fibers? The answer is from 2.0, CLR does support fiber mode. This means that there are hosting APIs using which a host can make CLR use Fibers to run its threads. So in effect there's no requirement that a .NET thread be tied to the underlying OS's threads. A classic example is that of SQL Server which hosts .NET in fiber mode because it wants to take care of scheduling directly. Head over to here (scroll down to SQL Server section) for an excellent read about this topic.
There's also the book Customizing the Microsoft .NET Framework Common Language Runtime written by Steven Pratschner which has a chapter on customizing CLR to use Fibers. I have already ordered the book. Once it comes in and I get a chance to read it, I'll post more about this.
Our team just moved to a new building in Microsoft India campus. A lot of people were going around checking out other people's office. I got asked couple of times about my workstation layout and thought I'll do a quick post on that.
Like most people in our team I use a dual monitor setup. Last time I estimated I spend about 12% of my life looking for things (40% of it for my car keys). So even though there are people who use 7 monitors I'm never going to join that gang and bump that number to 30% by adding the time to search for my app window. And Microsoft will definitely not fund those many monitors either :). So for me 2 is enough.
Both monitors I have, are standard HP1965 (19" monitors) hooked on to ATI Radeon cards. One of the monitors (the one on the left) is looped through a KVM switch and I can rotate that among the other 2 machines that I have. The other I have rotated in portrait (vertical) mode and use it primarily for coding. The image below should explain why
This provides a much better code view. In the font size I use (Consolas 9pt) I can see 74 lines of code vs 54 in the landscape mode. So this means 37% more!!! Since I have ATI card I use Catalyst Control Center to rotate the display.
I also prefer dark background and use white/light-color text on it. My eyes feel better with it. I keep both Visual Studio and GVim in dark color mode. You can download my vssettings from here and .vimrc from here.
That kind of rounds up the workstation layout that I use in office. I try my best not to work on the laptop directly. I TS on to it in case I need to use it for any reason. When I took the picture it was quietly napping on the other side of my office :)
It literally rains email at Microsoft (if you've been to Seattle/Redmond you know why :) )
I've always struggled to keep up with the email in Microsoft. When I joined I was stunned with the downpour. The number of email I got on the first day was more than what I got in a month in Adobe. The situation worsened when I went through team transition last month because for some time I had to listen to the email threads of both teams DLs (distribution list).
I have tried using various techniques to cope before. This included complex labyrinth of folders (I've met folks with 9 level deep folder nesting), rules, search folders, you name it!!
All of them failed until I saw this post from John Lam. This talks about reverse pimping outlook. Even though I didn't go to the extreme he did, I basically got the following done
This ensures that I read all emails that come to me, I never miss an email now. I go on hitting zero emails in the inbox couple of time a day. Couple of times a day I scan the followup folder to ensure that I have replied/taken-action on all emails in the follow-up folder.
Even though the process sounds complex it's working miraculously for me for the last two months. I can finally forget about email overload.
My outlook looks as shown below. It's more cluttered than John's version because I need to see upcoming meetings in the right pane.
It's been a drag maintaining two blogs for some time now. So going forward I'll shift to posting only on my personal blog. I'll be cross posting for some more time and then stop this blog.
The new address is: http://geekgyan.blogspot.com/
Point your aggregator to: http://geekgyan.blogspot.com/feeds/posts/default?alt=rss
We are moving in Microsoft India as well. We will move to the spanking new Building-3. While putting my stuff in the boxes supplied, I thought its a good time to announce my blog move as well :)
Someone asked on a DL about when to force a GC using GC.Collect. This has been answered by many experts before, but I wanted to re-iterate. The simple answer is
"extremely rarely from production code and if used ensure you have consulted the GC folks of your platform".
Lets dissect the response...
Production Code
The "production code" bit is key here. It is always fine to call GC.Collect from test/debug code when you want to ensure your application performs fine when a sudden GC comes up or you want to verify all your objects have been disposed properly or the finalizers behave correctly. All discussion below is relevant only to shipping production code.
Rarely
A lot of folks jumped into the thread giving examples of where they have done/seen GC.Collect being used successfully. I tried understanding each of the scenarios and explaining why in my opinion it is not required and doesn't qualify to make it to the rare scenario. I have copy pasted some of these scenarios with my response below (with some modifications).
In effect most usage are redundant.
Question is then what qualifies as a rare scenario where you want to do a GC.Collect. This has been explained by Rico Mariani (here) and Patrick Dussud (here).
‘In a nutshell, don’t call it, unless your code is unloading large amounts of data at well-understood, non-repeating points (like at the end of a level in a game), where you need to discard large amounts of data that will no longer be used.”
Its almost always when you know for sure a GC run is coming ahead (which you completely understand and maybe confirmed with the GC guys of your framework) and you want to control the exact point when you want it to happen. E.g.in case of a game level end you have burned out all the data and you know that you can discard them and if you don’t GC will start after 6 frames of rendering in your next level and you are better off doing it now as the system is idle and you’d drop a frame of two if it happened in the middle of the next frame.
And obviously you call GC.Collect if you found an issue reported/discussed in the forums and you have figured out a GC bug which you want to work around.
I would highly recommend seeing this video where Patrick Dussud the father of .NET GC explains why apparent GC issues may actually be side-effect of other things (e.g finalizes stuck trying to delete behind the scene STA COM objects).
What is the problem with calling GC.Collect
So why are folks against calling GC.Collect? There are multiple reasons
Both 2 and 3 are GC implementation specific (differs across desktop and Compact GC) stressing the first point which is most assumption are implementation details of the GC and may/will change jeopardizing the attempt to try out-guess the GC when to run.
A question posted on a DL was as follows
"I have an application that allows only one instance on the desktop, how do I force it to open multiple instance for some testing purposes".
Disclaimer: Note that this is kinda hacky and only relevant if you are a tester trying to break something. This shouldn't be treated as a way to achieve anything productive.
Since the user didn't explain which approach is used to ensure only one instance is allowed I'll try listing down the methods I know off and how I can break them.
Using named Mutex: This is the more resilient approach taken by applications like Windows Media player. Here the application tries to create a named Mutex with sufficiently complicated name to avoid collision. E.g. namespace.app.guid and then try to acquire the mutex. In case it fails to acquire it then an instance is already running and it closes itself. If it acquired the mutex it means it is the first instance and it continues normally. An approach is outlined here.
Even though this seems to be the most robust solution this can be made to fail as well. If an user has sufficient permission he can do a CloseHandle on a Mutex handle created by some other application as well. For this you don't even need to write code. Do the following
Enumerate the names of applications running and see if the app is already running: This uses a combination of Process.GetCurrentProcess and Process.GetProcessByName(), see an implementation here.
This is easy to break. To do a DOS (Deinal of Service or DOS) just create another application with the name that the app expects and per-launch it. To open two instances copy the application to another name and open that first and then the original application.
Enumerate Windows
This involves iterating through all the open windows in the system using EnumWindows and then seeing if a Window with a given name or classname is already present. Since the system doesn't guarantee uniqueness in either of the text or class name this can be broken in a similar approach to the first one. However, there are some complications to it as it is difficult to change window text from outside. However, a combination of code injection and SetWindowText win32 API should work.
When the system goes out of memory a OutOfMemoryException is thrown. Similarly for stack overflow a StackOverFlorException is thrown. Now typically an exception is thrown as follows (or the corresponding native way)
throw new System.OutOfMemoryException();
But when the system is already out of memory there's a little chance that creating an exception object will succeed. So how does the CLR create these exception objects?
The answer is trivial and as expect, at the very application start it creates all these exception objects and stores them in a static list. In case these exceptions are to be thrown then it is fetched from this list and thrown.
The consequence of handling Stack overflow is even bigger because once the stack has overflown calling even a single method in that thread is equally dangerous and can cause further corruption. That is the material for another post :)
Other than the exact when part this post applies equally for the desktop portion.
Disclaimer: This post is mainly indicative. When the GC runs is an implementation detail and shouldn't be relied on. This is not part of any contract or specification and may (most probably will) change.
The ECMA specification for Garbage Collection is intentionally vague about when an object will be collected (or freed up). The memory management cycle mentioned in the spec is as follows
As you can see the specification doesn't even need an implementation to do code analysis to figure out garbage. It can simply use scoping rules (used anyway by the compiler to detect valid variable usage) for garbage detection. The specification also doesn't specify eventually when the objects are collected. The only need is that it is finalized and freed unspecified time later than the time when it goes out of use. This convenient open statement lets each GC implementers to choose whatever they deem fit for the purpose. Since even thread is not specified a concurrent GC or a non-concurrent GC can be used.
However, everyone wants to know exactly when their platform's GC is run. Here goes the non-exhaustive list for the .NET Compact Framework's Garbage Collector
Obviously there can be small differences across various platforms on which .NET CF is implemented. However, the differences are small enough to ignore for this discussion.
Even though this list seems small it works pretty well across disparate systems like XBox and Windows Mobile. In the next post I'll try to get into why "production user code should never do a forced GC". I know that statement is a bit controversial (at least it got so in an internal thread).
Few people seem to know that the word Endianess comes from Gullivers travels. In Gulliver's travel where there were two types of people, the Lilliputs who cracked the small side of their soft boiled eggs and the Blefuscu who used the big side (Big-Endian). Since I'm well networked these days (over Orkut/Facebook/LinkedIn) I make a conscious decision to be Big-Endian while cracking an egg as its the preferred network endianess.
I do not want to delve into the holy endianess war especially because most modern processors allow hardware/software methods to switch it (reminds me of some politicians though :))
However, I do use bit/byte questions as the acid test for fly/no-fly interviews as suggested by this guy. One of them involves asking about the whole endianess business and a code snippet to find out the endianess of the current system. I'm usually looking for something as below
short a = 1; if (*((char *)&a) == 1) printf("Little Endian\n"); else printf("Big Endian\n");
Once upon a time a kick-ass developer I knew told me that a good developer needs to be multi-threaded and run the following threads
The same person also told me that real programmers do not blog, he asked me "Do you know about Dave Cutler or Linus Torvald's blog?". So I guess we can safely ignore him :)
I've been working for some time in Visual Studio Team System (first on the TFS server and then on the testing infrastructure). I was looking for a change and then I happened to talk with the GPM of the .NET COMPACT FRAMEWORK team. The following explains in brief what followed...
... and so I landed a job in the .NETCF Garbage Collector and other parts of the execution engine. I'm sure I'll be super busy as the team is heads down into getting Silver Light onto mobile devices and going cross-plat (I guess most folks have heard about SL on Symbian/Nokia).
What this means is that I can (or rather I have to) muck more with .NET (both desktop and CF) without any guilt and can claim that blogging about them is actually a part of my job. So what this means for this blog is that there'll be more hardcore stuff about .NET and an additional Tag called NETCF when I post specifically about it.
In case you are in India and want to work in a Kick-ass team delivering one of the most key technologies for the industry then drop me a line at abhinaba.basu @ you know where. Bragging rights will come for free when you point to all those cool WinMobile/S60/XBox/Zune devices and claim how you coded .NET for it....
Wish me luck...
For starters it doesn't include C++ or C#, even though your mom codes in it :) ...
A lot of people speaking English natively forget the importance of mother language due to its predominance. They take their language for granted. However, each year a bunch of languages become extinct, the latest being Eyak, which got extinct exactly a month ago with the death of Marie Smith Jones the last native Eyak speaking person.
To me this day (21st Feb) is even more special because on this day in 1952 people in Bangladesh laid down their lives while demanding the right to use their own (and mine) mother language, Bangla.
I believe that if we don't actively try to preserve our mother language they will slowly become extinct. One of the most important things to preserve a language is to ensure that they are better covered by technology. Until XP complex script handling was not enabled by default. This resulted in Bangla and other Indic language to be rendered completely wrong on XP. This was a serious deterrent to use Bangla on Windows. I used to have Bangla signature in my email and got countless replies indicating the spelling is wrong. I always replied back to them about how to turn the complex script handling on. Things are changing rapidly, Vista has this on by default and with better keyboard and font support I'm sure using Bangla on Computers will become really easy.
নমস্কার
Someone saw a message in their Team Foundation Server history which was "Edited by God" and asked how is this possible on the msdn forum. Someone actual read my blog (or some other's but I tend to believe mine 'cause I'm linked in that page) which shows exactly how to do that. So now I have a poor-joke (PJ) of mine being featured in msdn :)
For the last couple of days a vast majority of the movie that I'm seeing is somehow landing in Africa. Since I didn't choose any of them (Amit did), it wasn't a conscious decision. Example include The Interpreter, Blood Diamond, Duma.
In all of these movies African music is used in the background, and I've began to like them a lot. I have no idea about the tribe/nationality of these but the sound is just enchanting. Any idea where I can get some good original African music on the web? Buying is also an option if Indian stores/sites have them (which I heavily doubt).
Sometime back I posted about variable parameters in Ruby. C# also supports methods that accepts variable number of arguments (e.g. Console.Writeline). In this post I'll try to cover what happens in the background. This is a long one and so bear with me :)
Consider the following two methods. Both prints out each argument passed to it. However, the first accepts variable arguments using the params keyword.
static void Print1(params int[] args) { foreach (int arg in args) { Console.WriteLine(arg); } } static void Print2(int[] args) { foreach (int arg in args) { Console.WriteLine(arg); } }
The above methods can be called as follows
Print1(42, 84, 126); // variable argument passing int[] a = new int[] { 42, 84, 126 }; Print2(a); // called with an array
Obviously in the case above, using variable number of parameters is easier.
If we see the generated IL for Print1 and Print2 using ILDASM or Reflector and then do a diff, we will get the following diff
.method private hidebysig static void Print2(object[] args) cil managed .method private hidebysig static void Print1(object[] args) cil managed { .param [1] .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() .maxstack 2 .locals init ( [0] object arg, [1] object[] CS$6$0000, [2] int32 CS$7$0001, [3] bool CS$4$0002) L_0000: nop L_0001: nop L_0002: ldarg.0 L_0003: stloc.1 L_0004: ldc.i4.0 L_0005: stloc.2 L_0006: br.s L_0019 L_0008: ldloc.1 L_0009: ldloc.2 L_000a: ldelem.ref L_000b: stloc.0 L_000c: nop L_000d: ldloc.0 L_000e: call void [mscorlib]System.Console::WriteLine(object) L_0013: nop L_0014: nop L_0015: ldloc.2 L_0016: ldc.i4.1 L_0017: add L_0018: stloc.2 L_0019: ldloc.2 L_001a: ldloc.1 L_001b: ldlen L_001c: conv.i4 L_001d: clt L_001f: stloc.3 L_0020: ldloc.3 L_0021: brtrue.s L_0008 L_0023: ret }
Only the lines in Green are additional in Print1 (which takes variable arguments) and otherwise both methods looks identical. In this context .param[1*] indicates that the first parameter of Print1 (args) is the variable argument. The ParamArrayAttribute is applied to the method to indicate that the method allows variable number of arguments.
Effectively all of the above means that the callee is not really bothered with being invoked with variable number of arguments. It receives an array parameter as it would even without the param keyword usage. The only difference is that the method is decorated with the some directive and attribute when param is used. Now it's the caller-code compiler's duty to read this attribute and generate the correct code so that variable number of parameters are put into a array and Print1 is called with that.
The generated IL for the call Print1(42, 84, 126); is as follows...
.method private hidebysig static void Main(string[] args) cil managed { .entrypoint .maxstack 3 .locals init ( [0] int32[] CS$0$0000) L_0000: nop L_0001: ldc.i4.3 ; <= Array of size 3 is created, int32[3] L_0002: newarr int32 ; <= L_0007: stloc.0 ; <= the array is stored in the var CS$0$0000 L_0008: ldloc.0 L_0009: ldc.i4.0 ; push 0 L_000a: ldc.i4.s 0x2a ; push 42 L_000c: stelem.i4 ; this makes 42 to be stored at index 0 ** L_000d: ldloc.0 L_000e: ldc.i4.1 L_000f: ldc.i4.s 0x54 L_0011: stelem.i4 ; similarly as above stores 84 at index 1 L_0012: ldloc.0 L_0013: ldc.i4.2 L_0014: ldc.i4.s 0x7e L_0016: stelem.i4 ; stores 126 at index 2 L_0017: ldloc.0 L_0018: call void VariableArgs.Program::Print1(int32[]) ; call Print1 with array L_001d: nop L_001e: ret }
This shows that for the call an array is created and all the parameters are placed in it. Then Print1 is called with that array.
Footnote:*interestingly it starts at 1 and not 0 because 0 is used for the return value.**stelem takes the stack [..|array|index|value] and replaces the value in array at index with value
Cross posted here
A friend asked me the differences between the two. Here goes the answer
int[,]
This represents a two dimensional rectangular array. Let's take the following array definition
int[,] ar = new int[3, 3] { { 0, 1, 2}, { 3, 4, 5}, { 6, 7, 8}};
The array actually looks like the following
Which as we can see is rectangular. This kind of array is required when for every items represented in the rows there's exactly the same number of items represented in the column. E.g. a board game like chess.
int[][]
This is defined as array of arrays or as jagged arrays. They are created as follows
int[][] ar2 = new int[3][]; ar2[0] = new int[] { 0, 1, 2 }; ar2[1] = new int[] { 3, 4 }; ar2[2] = new int[] { 5, 6, 7, 8 };
The array looks like
Here the number columns is not the same for each row. A good example of this kind of usage is when we have a array of polygons where each row contains the coordinates of the vertices of the polygon. Since each polygon has different number of vertices (square, triangle, ...) this data-structure is useful in defining it.
Since it's jagged it has to be referenced carefully.
Console.WriteLine(ar2[0][2]); // Prints 2 Console.WriteLine(ar2[1][2]); // Crashes as row 1 has only 2 columns
The jagged array can be padded on the right to convert it to a rectangular array, but this will result in a lot of space wastage. In case of the jagged array the usage of space is sizeof(int) * 9 but if we pad it we will use sizeof(int) * max (column). This additional space can be significant.
Note:
int and 2D arrays were used only as example. This applied equally well to other data-types and higher dimensions.
One of the things I didn't like in Ruby at all is the support for method overloading. You have no ways to support it in a straight forward way other than to define a single method that takes a variable number of arguments.
def foo(*f) f.each { |a| puts a } end foo("Hello", "world")
What the above does is that it converts the multiple parameters into a single array and passes it to the method call. I think this is really bad because method overloading is a very basic requirement.
However, Ruby seemed to support another really weird feature of expanding arrays in method calls. What this means is that if a method accepts a number of parameters and it's called with an array then the array is expanded such that the i'th element in the array is passed as the i'th argument.
def bar(name, address, age) puts (name, address, age) end details = ["Abhinaba", "Hyderabad, India", 42] bar(*details)
So details[0] is passed to the name parameter and details[1] is passed as address, and so on
>> Cross posted here
Specially for folks using the C* languages (C/C++/C#) and Java it's very important to learn dynamic/functional languages.
There are three reasons.
I think the fun part is the most important.
``I think that it's extraordinarily important that we in computer science keep fun in computing. When it started out, it was an awful lot of fun. Of course, the paying customers got shafted every now and then, and after a while we began to take their complaints seriously. We began to feel as if we really were responsible for the successful, error-free perfect use of these machines. I don't think we are. I think we're responsible for stretching them, setting them off in new directions, and keeping fun in the house. I hope the field of computer science never loses its sense of fun. Above all, I hope we don't become missionaries. Don't feel as if you're Bible salesmen. The world has too many of those already. What you know about computing other people will learn. Don't feel as if the key to successful computing is only in your hands. What's in your hands, I think and hope, is intelligence: the ability to see the machine as more than when you were first led up to it, that you can make it more.''
Alan J. Perlis (April 1, 1922-February 7, 1990)
I work on the UI action recorder and it has a strict performance requirement. The tool dumps the time it takes to record each action in it's log and that is compared against the maximum allowed value (otherwise the system will seem sluggish). To do this obviously we need fancy charts, as everyone likes them, other than of course the alpha-geeks :).
However, I like the console chart. Way back my mom used to work on Main-frames that ran COBOL on them and dumped out business data on paper at the end of the day. These reports had these printed bar charts.
I wrote a small ruby script to dump these charts on the console. The output looks like
D:\MyStuff\Code\Ruby>perf c:\logs\Recorder_20071118_144855.843.log c:/logs/Recorder_20071118_144855.843.log ===============================> 640 ******************************************************************************** 0 * 109 ************* 0 * 46 ***** 0 *
Serves the same purpose as their fancier counterpart but manages to look uber geeky.
>> Cross-posted here...
The .NET platform and the languages on top of it have limited or no support for range of values. Data ranges are one of the most common data-types and somehow it's not there. Funnily most programmers do not even seem to miss it (unless of course if you have used Ruby).
How would you specify a valid range of age and validate user data against it? If you know the maximum and minimum values, at max you'd define a MaxAge and MinAge consts and strew the code with if(age < MinAge|| age >MaxAge). Or maybe you'll define a class to encapsulate this and add a IsValid method.
However, in Ruby, Range is a standard DataType like say string. To do the above processing you'd do
age = 1..120 print age.include?(50) print age.include?(130) print age === (50) # more easier way to do include? test using the === operator
So intuitively you create a range using start..stop.
Creating a range of data is also very simple. Say you want to generate the column numbers for an excel sheet, you'd do the following
column = 'A'..'ZZ' column.to_a # creates an array of all the values column.each {|v| puts "#{v}\n"}
Similarly ranges can be easily created for any class by implementing some special methods. On ruby the support of Range is in the compiler and makes the code very easy to develop and intuitive.
>>Cross posted here
Windows Home Server team has a nice light-hearted site up at http://www.stayathomeserver.com/. All of it was funny, until I reached the page http://www.stayathomeserver.com/book.aspx. It says "daddy wants to give mommy a special gift.... So he buys a stay-at-home server". That's not funny, "Wife Acceptance Factor" would be reflecting nitrogen freezing point for a home server.
You can sneak one in, understate the price and show all the image streaming to kinda buy acceptance, but a gift, no way :)
Sometime back Hutch phone in India got bought over by the international phone giant vodafone. They re-branded Hutch in India to Vodafone.
Now when I call up home and the phone is busy I get a recorded message in Bengali which means "The Vodafone number you're trying to call is busy". All that is good but the problem is that vodafone in Bengali exactly means foolish phone. So I just hang up and wait for the foolish-phone to get free.
Cross posted here...
From the HitchHiker's Guide to the Galaxy.
"The Ravenous Bugblatter Beast of Traal is a creature that hails from the planet of Traal, and will eat anything. If you are to encounter one, the Guide tells you that it's impossible to slay, so you should wrap a towel around your head. This creature is so mind-bogglingly stupid that it assumes that if you can't see it, then it can't see you."
I felt like one while on a road-trip to Visakhapatnam and surely you'll feel like one on Indian roads. We were going at high speed and suddenly we see someone crossing the highway. We honked hard and the person simply looked down. So the idea is that, if he can't see you, then you don't exist. Or maybe they were using the SEP field technology.
In the following video watch the first person crossing the road and next a cyclist goes in the wrong direction as we wiz past at 120kmph (75 miles/hour).
I got this question from someone just starting out on the .NET platform. He is used to hit F12 (go to definition) on types and then figure out the inheritance chain. However, he couldn't do that say on a number (int) or array.
The solution is to write a simple recursive routine as follows
static void Dump(Type t) { if (t != null) { Dump(t.BaseType); Console.WriteLine(t.ToString()); } }
The routine can be called as follows
Dump(typeof(int));Dump("abc".GetType()); Dump(1.GetType()); Dump(typeof(EventAttributes));
No marks for guessing the output though :)
Windows gives examples of "Kitchen Computer" or "Mary's Computer" for setting the name of a computer (Computer Name tab in System Properties). But I'm sure that most people don't name their computers that way and show off a bit of creativity in it.
Previously I used to use names from Asterix like GetAFix for my main dev box. Now I exclusively use names from Hitchhiker's Guide to the Galaxy. Some of the machines I use are named as below
What name do you use?