Home
Main website
Display Sidebar
Hide Ads
Recent Changes
View Source:
WhyIHatePerl
Edit
PageHistory
Diff
Info
LikePages
I felt the need to rant, so why not? :) !!Nest types suck In perl you can't do anything obvious like create a hash of a list of strings trivially, you have to spend your entire time worrying about references. Why? I don't know. !!A Gazillion obscure operators and magic variables In perl you're never sure the operator this person is using is. Perl has operators and variables names after almost every punctuation key on the keyboard. (Pop quiz: Which punctuation keys on a standard qwerty keyboard, *aren't* valid perl variable names?) ''True, but you don't need to know or use these variables. Just because you *can*, doesn't mean you *should* :) $! is the string message for the last error, $@/$$/$% do things with references to those data types, $# is the length of a list, $^ is magic for which OS you're on, etc etc. But not knowing this doesn't make perl any harder to use. Most punctuation also does something in C -- you're just more used to them.'' ''Isn't this based on the assumption that "use" is only writing code? I would argue that since you (and others) will end up having to read, and interpret the code at some point, complex and obtuse constructs like this do make the language harder to use. Since they are there, they will be used, so you have to know them to be able to understand the code.'' -- Stephen Lewis ''Also, just to be pedantic, the node is WhyIHatePerl, not WhyCIsBetterThanPerl ;)'' --Stephen Lewis This was ment as a random rant, as someone asked me what I disliked about perl, so I thought I'd jot a few of them down. It's not ment to be a complete critism, most of it is mostly due to my not knowing the language properly. The thing is in perl you *can* write nice and easy to read and maintain programs, however people don't. Sure ''I'' can avoid these things, but it doesn't help me when I'm trying to debug some body ''elses'' script. C uses a lot less punctuation than perl, this is easily proven by the fact that perl uses mostly the same punctuation as C, and then adds it's own ones :) I don't think C and Perl really should be compared. They are completely different problem domains. I've got a rant growing somewhere about C too :) Compared to python, perl looks like executable line noise. ''And [Python] looks like executable whitespace. These variables are actually hardly a design decision on [Perl]'s side - 99% of them existed in [AWK]. Much of the linenoise comes from the [AWK] and [SED] heritage actually. The majority of it is loathed by many [Perl] hackers as well. Too much of I/O is controlled by global special variables; Larry himself has said this situation needs fixing. Of course not much can be done for [Perl]5. Unlike the [Python] and [PHP] folks, we don't go breaking people's old scripts willy nilly :)'' --AristotlePagaltzis ''[Perl] didn't get its line noise from [AWK]. All [AWK] has is the $ operator for getting from a field, eg $3 will get the third field, $x will get the field for the number held in x. [sh] has $ on it's variables and shares some with [Perl], but many are unquie to [Perl], eg $# is the output format for printed numbers in [Perl] and the number of command line arguments in [sh].'' --JonPurvis ''Of course the punctuation variables don't all come from the same source. When you mix four different languages with their own spirit each you won't be replicating any of them exactly.'' --AristotlePagaltzis !!Simple things are hard Someone once said that the definition of a low level language is one that requires you to spend your time worrying about the irrelevant. Perl must indeed be a low level language. Trying to figure out how to pass a list to a function, create a local variable in a function, nest types are all things that are difficult to get "right". You have to know a magical encantation to do them. Why don't they do the right thing? ''I don't understand the question... To pass a list, you just pass it. Or is the problem that all arguments get flattened into one list? That's a fair gripe. Then again, how do you pass a list in C? Pass a pointer? Then you have to pass a list count as well.'' Lists get flattened, variables by default are global, nested types aren't really nested (they're just references). The point of a scripting language is to get on and do what you want, not spend time thinking about how you are going to achieve it. I'm sure there are other examples of perl doing counter intuitive things by default and requiring you to work around them. These are mostly historic since perl grew out of a smaller language into a bigger one. But I think these are good examples of why you shouldn't use perl for a large project. Perl is good at parsing text files and outputting a nice summary, or munging it into a different format. Perl is not something that you should be writing large projects in. Yet people still do. (People still write large user space projects in C too for some unknown reason). To effectively work on a large project you've got to manage complexity, with perl unless you are very strict, the complexity gets away from you. The thing is most programs start 'small' (I'll just write something that parses subscribe/unsubscribe requests and updates a sendmail alias) but ends up growing over time into a monster (majordomo...) Compared to almost any other language, Perl makes you spend a lot of time working with the irrelevant. ''Perl lets you know about the reference as well as the referee. Other languages hide the reference from you without working fundamentally differently. How is that better?'' --AristotlePagaltzis ''Because if things are designed well enough (!) you don't need that low level of access, even to do unintended things. Higher order functions, complex and nested types (lists, dictionaries/hashes, strings, in any combination), and a strong but lightweight object system (i.e. minimal syntax and typing) let you hack things up for the unusual case without making the usual case burdensome. C hides the ability to check or change the flags bits when arithmetic operations occur but assembly lets you do this any time you want, or to have a different function call method (e.g. for tail calls). We should all code in assembly all the time. How is that better?'' --JaredUpdike ''But that is no "low level of access." Conceptually, there's no difference between any of the languages, as "nested types" are always implemented in terms of the basic data types and references. What differs is just the syntactic sugar on top. Perl requires the programmer to be more explicit about references because arrays in list context are implicitly flattened, and you need to be explicit to avoid that. But OTOH, concatenating lists, passing flattened arrays to functions and the like requires a lot more effort in languages that are not Perl. Perl is more list-ish by default, and simply optimizes the syntactic sugar in a different direction as far as this issue is concerned. This doesn't have anything to do with level of access. Now you may certainly prefer a different flavour of sugar than I do -- and I really rather prefer the list-y functional feel of Perl --, but that doesn't make your preference more valid than mine or vice versa.'' --AristotlePagaltzis !!There's More Than One Way To Do It Perl people say this is a good thing, but the problem with theres more than one way to do it, is that noone ever does it the same way twice. To properly read a program you have to understand the 'idioms' that that program is written around. In Perl it's difficult to realise that "ah, thats a switch statement, I can see what that's going to do" because in perl there is no switch statement, you can roll your own (a nice idea), but, you can get half way through and discover someone's modified their idea of a switch statement slightly and now it has a side effect you didn't realise until you read the code very very carefully. In most languages you can learn a couple of constructs (for, while, do..until, if...then...else, functions) and you've learnt a good chunk of the language and can read most of it. (Even C++ which has a huge number of things (virtual private classes? who on earth would use such a thing?) you learn about the various flow control structures, and how to define/call functions/methods, and you can follow a good chunk of C++), however in perl, since theres so many ways of doing anything you have to learn all the idioms before you can read a sizable chunk of perl code since they are all used, randomly. ''You're hanging your entire argument on switch statements here. [Perl] does not have one because all switch statements found in other languages suck to varying degrees and Larry decided we don't want one we'll have to work around rather than with. I haven't been particularly irked by that decision in practice.'' --AristotlePagaltzis !!There's More Than One Way To Do It, part 2 (GlynWebster's two cents.) When Larry Wall and Perlers say "there's more than one way to do it" they seem to be talking about syntax rather than the semantics. They really mean "there's more than one way to say it". I'm not sure that Perl gives anyone more ways to actually do things than any other well-stuffed scripting language. It gives people lots of ways to write down individual statements, which gives them a sensation of freedom while coding[2], but only seems to lead to confusion and trouble later on. The languages that really give you a lot of ways to do things, like CommonLisp, are far less popular. I think this emphasis comes from Larry Wall's background in linguistics. With a natural language having lots of ways to say things is a good thing, but semantics are something that linguists try not to think too deeply about. The semantics of natural languages are so poorly understood that it's a bottomless pit best to stay out of. But computer languages are not like languages. They are "notations" more akin to the various notations used in mathematics. Larry Wall don't believe this. Larry Wall seems to be be paying more careful attention to semantics in his "Apocalypse" series of design documents, but he doesn't seem to learnt his lesson about syntax -- Perl 6 looks like it will be even hairier than Perl 5. He's more than smart enough to design a computer language, I know I couldn't do what he's done. I just don't feel like following him because I don't think he has taken the right approach, and has the wrong temperament for his task -- a belief that elegance is possible and a mathematician's urge to reduce things to their essentials seem to be called for. ''LarryWall believes that humans are linguistic animals, not that computer languages are like natural languages. Mathematical language is precise, but not the way we think. Larry believes usable languages must follow the way we think, not make us think the way the language works, and I absolutely agree. Reducing is not the answer. If animals, which is a category, were all called similary, say "ani"+syllable, and a cow as anico and a cock was anica you might send someone to milk the cock by accident. Things have to be sufficiently different, even if they're similar. You'll also notice that [Perl]6 is all about reducing similar mechanisms to identical foundations.'' --AristotlePagaltzis !!Cause doesn't always preceed effect. Perls operators like "unless" mean you can spend a long time reading a block of code before realising that the entire block doesn't get called because there is an "unless" at the end of it. Cause should preceed effect, not come half a program later. <Matthias> hmmm... and unless is nice in some cases... it can really help making code readable... unless you abuse it <Isomer> I think that sentance just proved my point ;: ''(Later addition) If you are using a complex condition which is composed of many smaller parts that may themselves be broken down into subconditions, making the condition part take a long time to read, memorize (of which different people are differently capable) and parse while you are trying to reach the conclusion of what it is all really trying to achieve at the essence of the matter - you might even start to get confused because the whole thing is getting too long to memorize for ''anyone'' -, then it makes sense. Now wouldn't that have been much easier to read if I'd put the "it makes sense" up front and left the longwinded condition trailing behind?'' --AristotlePagaltzis ''Again, just because you can code something in one way, doesn't mean you should. I personally don't use the 'unless' keyword because it doesn't flow the same way a C program would. But then again, it is not uncommon in C to see do { block } while (0); This isn't exactly crystal clear either unless you are a seasoned C programmer.'' The problem is that most of the code at least I interact with is written by other people, or at least is modified by other people. If a program is small, then it's irrelevant, people will just tend to rewrite it instead of modifying it. I find very few perl programs that I honestly thing are 'readable' and 'clearly throught out', this is perhaps because I'm not very experienced in the language, but when compared to when I was teaching myself C, I find perl to be much worse. The thing that made me add this on this list was trying to debug some program that appeared to go off and do something totally unrelated, then had an unless over a screen away which made the entire point moot. Probably it evolved from a single line with an obvious 'unless' at the end of the line, which grew as this case got more and more complicated into the monster I was forced to do battle with, but it's symptomatic of the problems you end up with in perl programs. This is probably a special case of TMTOWTDI, but always something I felt very jarring. !!Perl implicitly does things behind your back. Perl's $_ operator saves a lot of typing, but makes your program have a large hidden dependancy. Like the "more magic" switch of lore, changing something unrelated that does absolutely nothing obvious can cause your program to crash. Is it safe to insert some code in the middle of this block? Who knows! It could disrupt the fabric of space time that this perl program exists in. ''Um, that's what __local__ is for.'' --AristotlePagaltzis ---- !!Some additional discussion from the page of JaredWigmore: I dislike ...[Perl] (too simple, too slow and doesn't scale)%%% %%%''... I don't like [Perl] either :) -- PerryLorier'' %%%''... I also think [Perl] sucks perhaps a couple of LoveLace, no matter what you compare it to! :) Try [Python], it's great! -- zcat(1)'' %%%'' [Perl] combines the worst aspects of [C], [BASIC] and LineNoise -- Anon'' %%%'' I don't like [Perl] either. I got about ten pages into the manual (somewhere around the "you are not supposed to understand this" part) before I started to think I was having my leg pulled. Then I discovered [Python]. ... --GlynWebster''%%% ''Heathens and philistines, all of you! :) A language is only bad if it is not expressive enough. If it is, and Perl is plenty expressive, then it's the programmer who makes it what it is.'' "If it was possible to write programs in English, we would discover that programmers can't write English" --LarryWall ''[Perl] is easy to abuse because it's so expressive you can do things in any number of ways. Unfortunately, it is so easy to successfully say something the computer will understand that few people bother to think about how to say it ''well''. [Python] is entirely on the other extreme of the spectrum, and I find that extraordinarily obnoxious.'' --AristotlePagaltzis ''But Python __is__ an attempt at saying something well. There's elegance and forethought in the design of Python that's missing from Perl. "Saying something well" in software involves making the entire program well-structured and comprehensible to others. Perl's great number of syntactic options at the expression level don't help there. --GlynWebster'' %%% ''That you can change the sequence of things in a sentence - that is what my point is about. It does not let you chose between "I want to say the same thing differently depending on the situation" vs "Depending on the situation, I want to say the same thing differently" or even "Differently do I want to say the same depending on the situation". Neither is the verbosity is up to the programmer to choose in to [Python]. I find it very frustrating how [Python] doesn't let me get to the point - and no, that doesn't mean my [Perl] code is compact and incomprehensible, au contraire. I recently [argued such a point|http://www.perlmonks.org/index.pl?node_id=239615] with RandalSchwartz (who originated the term "[Perl] hacker"). [Perl] gives you the freedom to do what__ever__ you want. The problem, as the LarryWall quote I cited hints at, is more due to the fact that, well, the majority of programmers are mediocre at best, so [Perl] is a dangerous tool in their hands. It doesn't constrain bad habits at all so they end up writing horrid [Perl] code, where [Python] would have forced them to follow a decent style. Why's that a problem? Because an advanced programmer who (should) no longer be in need of those tight confines can't escape them. [Perl] is not a language to learn programming with; it's a language to get your job done. Just like [Pascal] is a neat language for a beginner to start out with, but not for an expert to get things done in. --AristotlePagaltzis'' The thing with Pascal is that it was impossible to do most things. Standard Pascal didn't treat files like most newer OS's did (a stream of bytes? wazzat?), but it's big failing was that the size of the array is part of the type, and there was no way to write a generic function to handle arrays of varying sizes. Since strings were a kind of array, you couldn't write a function to take a generic string. Sure, langauges like TurboPascal resolved most of these issues in incompatible ways. Delphi shows that Pascal can be a nice language when "touched up". Perl may be expressive, but the problem is that you have to maintain other peoples perl programs, and since other peoples Perl programs are difficult at best to modify, you have a problem. while this may not be the language's fault, it __is__ a problem with the language IMHO. --PerryLorier ---- Exactly. What I hear sounds like contradicting logic to me: # Perl is great because it frees you to do things the way you want and doesn't force you to do things a certain way. # But newbies are wrong for complaining about stubbing their toes trying to do simple things[3] the simple, obvious way; they should learn Perl for real and stop thinking in their preconceived (i.e. simple/elegant/obvious Scheme/Python) way, instead think in the preconceived Perl way. I'm exaggerating but as a newcomer (constantly warned about Perl but forced into it against my will because other people who do understand it used it for some scripts they no longer maintain-- probably poorly written ones at that) I want to try to vent my frustration without trolling too much. I will be gracious and try to take the long view: Perl is very hard and doesn't make sense to newbies, but once you get it all, it makes very much sense in its own sort of way. Good Perl hackers (and there really are such people! even I would admit) and advocates are rightly defensive about their language, but may have forgotten how long and hard they worked to get there (and it feels good to stand up there looking down on those who don't know what you know). If you don't want to learn a language that takes a lot of time and energy to understand well (enough to do arguably simple things), then don't learn Perl. The problem is, other people use Perl so I have to whether or not I want to. That's where my frustration is coming from: things just don't work right the first time, and I have learned and used many new languages in the last 6 years that did work right the first time: Lisp, Python, Scheme, OCaml, Haskell, etc.[4] P.S. If LarryWall was trying to reproduce the chaos, power and ambiguity of natural languages he hit the $nail on the $head. Kudos to Perl for being that one big loveable hateable monster. Just like the English language: it's easy if you grow speaking it natively. --JaredUpdike ---- Well, I remember very well how I took my first steps with Perl. Coming from Pascal, Assembler and C, the only real clincher was understanding lists as first-class citizens. That was the one qualitative step I needed to understand the language. Ever since, learning has been purely gradual. And yes, there are very obscure aspects of the language, most of which stem from its awk/sed heritage (like nearly all of the strange punctuation variables). I learned awk, sed and shell long after Perl, and would frequently go "oh, so that's where Perl got that from." They are very useful in oneliners, but good Perl hackers avoid them in lasting code, and they only really matter if you're maintaining a script written by a Perl hack (as opposed to Perl hacker). The big reasons I can think of that people have trouble grokking Perl as such (rather than any particular codebase) are a) references b) context sensitivity b) functional constructs. * As for references, well people have trouble understanding pointers too. All I can say is "get over it, it's just a phase." Understanding the concept of "something that stands for something else" in any of its forms is crucial to doing any non-trivial things. * Context sentivity is pretty unique, and if you have trouble keeping interacting layers of things straight in your head, I admit they can cause surprises. Context issues have caught ''me'' out a couple of times; though for the most part context fits the way my brain works. * Functional constructs, well, all I can say here is "get over it." Having understood and used them, I balk every time I find myself in a language where I have to make do without. But you said you know several functional languages, so those can't be your problem. Then again, since you've basically just said "Perl sucks, I can't read it," I can't say much more than this either. --AristotlePagaltzis ---- !!! AristotlePagaltzis and his soapbox [Perl] has weaknesses, but it follows the principle of [Mutt]: all [ProgrammingLanguage]s suck, this one just sucks less. If you read this page from a [Perl] hacker's view, you will continuously stumble over three things: # The original author is unwilling to learn references, which are the sole key and foundation to complexity and power in [Perl]. You may argue that you don't want to do so; fine, then [Perl] is not for you. But that the language separates the reference from the referent can in no way be construed as a weakness. Au contraire, it gives you control. # Most of the people say "well I couldn't be bothered to learn [Perl] thoroughly" often followed by something along the lines "things didn't seem how I expected them". Well, [Perl] is [Perl]. If you wanted to learn a variation of some language you know, then why did you try [Perl] in the first place? If you're approaching something new with preconceived notions, you're going to return to your old ways pretty soon. # The argument that "you ''can'' write clean [Perl] -- but people don't!!" comes up often. To that I say "real programmers can write [Fortran] in any language." !! Keys to [Perl] The first I have to say is that [Perl] is ''hard'' to learn. It is optimized for ease of ''use'' rather than ease of learning - a concept that seems to be foreign to modern computing (cf [GUI]s). It is not a language I would give a programming beginner to learn with, either, for exactly that reason. You don't put a greenhorn who just got his driver's license in a 200 HP sports car either, nor on the wheel of a 50 ton Mack truck. In that sense, [Python] fills an important gap - many people only write a few lines of code occasionally, and they're better off with a tool that guides them. If you only want to write a few lines of code occasionally, don't learn [Perl]. You'll only end up hurting yourself. A lot of people have, and the result is literally hundreds of thousands of awful scripts floating around on the web. Secondly, although its [C]-like syntax and [C] heritage may have you thinking otherwise, [Perl] is a list oriented language. It understands arrays as a type natively - in contrast, arrays in [C] are syntactically glorified pointers that, as far as the language is concerned, point to a single value. All variables in [C] represent only a single value; it has no notion of a list. [Perl] is much closer in spirit to [LISP] than [C], and indeed there's a lot of crossbreeding between [LISP] and [Perl] hackers. (I love [LISP] as well, myself.) Lastly, there's the issue of references I mentioned before. Any high level language builds complex nested structures out of simpler ones. [Perl] is no exception, it just makes this process explicit and in that way also lets you distinguish between the referent and the reference, where other languages conceal the latter. That said, in simple cases, [Perl] lets you pretend the reference isn't there, and my experience is that with a certain fluence in data structure layout for [Perl] code, the simple cases account for 60-95% of all uses, depending on what you are doing. The derefencing syntax for more complex cases is rather ugly and not something even [Perl] hackers cherish, though. ([Perl]6 promises to relieve this.) All that said, it isn't very difficult. With a bit of thought you should achieve any kind of manipulation you wish, something lanugages which hide the reference from you can't always offer. If you want to learn [Perl], take your time to understand how (de)referencing, it is the sole key and mechanism to complexity management in [Perl] - it might be inconvenient to learn, but ''all'' advanced mechanisms in the language hinge on references. Once you master them, all of the language is at your command. !! Why shortcuts are good From command line switches to the infamous ''$_'' variable to file operations, you can let [Perl] do a lot of your work when you can't be bothered to spell it all out. This does not mean you always should, but makes development a lot easier. I rarely know beforehand exactly how I am going to implement a program; being able to take shortcuts while I work on it until the final form crystalizes is very convenient. These shortcuts also improve maintainability if used in appropriate places, as well - the reader of a piece of code does not have to parse a lot of explicit red tape to come to the conclusion that it's just red tape and can be ignored in the greater scheme of things. The actually meaningful bits make up more of the code and so get more attention. O.c., abusing abbrvs mks anything < rd'able; I often go back once I have settled on a certain structure and remove or add shortcuts in order to make the coder clearer. Writing good [Perl] means finding a proper balance. But you ''can''. Other languages keep you perpetually slanted. !! A bit of petrol on the fire There's no direction in [Python]. No really. Guido and his crew don't (didn't?) even have any idea how the new language features in the [Python] 2.2 to 2.3 transition should be addressed. And they're going to break old code by changing the way established data types work. (The [PHP] folks have been doing this forever of course and noone seems to care. Namespaces? Wazzat? (The core functions are still getting lumped into the main global namespace with name prefixes.)) [Perl] has a long history of organic growth as well as any complex system must, but there's always a long phase of design and rethinking involved for major changes, and they lead to a new version of the entire language rather than just its implementation. Meanwhile the [Perl]5 compiler will swallow most [Perl]3 code unchanged without complaint (the first version that reached any significance). [Perl]6 is breaking this tradition on the grounds that the language needs an overhaul, and that there will be both a true [Perl]5 compiler that targets [Perl]6's VirtualMachine as well as a lesser P5 compatibility mode in [Perl]6 itself. !! I am not trying to get anyone to use [Perl]. But nearly all of the criticism on this page hinges on the fact that people don't know [Perl] well enough (and I'll be so indignant to assume that the rest is only accidentally directed at real weak points because they're unavoidable). I don't see why a [Python] or [Java] or whatever advocate would write about why he hates [Perl] when they haven't bothered to learn it, where it would be much more logical to write about what they love about their favourite language. ---- [2] I think a similar, pleasant feeling of busyness while coding explains some of the popularity of [C]. "I'm doing lots of work, I must be getting a lot done. Right?" [3] I claim that arbitrarily-nested compound data structures (lists, dictionaries/hashes and all possible nestings) are simple things. Any book on Scheme will cover them in the earliest of chapters. [4] When I say "work right the first time" I usually mean syntactically or semantically, not algorithmically or without bugs. But there have been those times when even a complex algorithm I wrote worked the first time: it happens sometimes in Python and frighteningly often in Haskell (or OCaml). And while I'm talking about Haskell, the best thing is that it DOES change the way I think, giving me newer and better and higher ways to things (I didn't even really know were possible to do!) that you really CAN'T do in Perl, despite the big-time claim that Perl let's you do anything you want, even unintended things. %%% ''[Disagree. | http://hop.perl.plover.com/] Also, I have this exact experience with Perl; I think of something, and the first time I write it down, it works. Syntactically, always; in terms of logic, about 80% of the time. Maybe that's why I am so fond of the language and why you are not. --AristotlePagaltzis'' I think I understand your point now. It's all in how you're used to looking at things and how you like to look at things. Perl is just very different, with a higher bar to entry (which many do not get over, including me!) and very different from how I like to do things. My last jab is that I meant by "things work right the first time" that "things work right the first time ''the first week'' I've been programming in that language at all!" Truthfully, even Python did not do this for me, but OCaml (and Haskell) did: I coded Random Search Trees the first week I had ever touched OCaml (despite the fact that OCaml is very different from anything I had seen before that time) and once I got it to compile, it ''worked right the first time''. If you coded something as subtle as Random Search Trees in Perl the first week of touching Perl and it worked literally ''the first time'' you ran the program, then I bow to you and Perl. Cheers! --JaredUpdike. I hate Perl. My is redundant, if I have to put my before everything, what is the point. Just let me declare something globally if I want to, rather than having to declare everything else as my. Also any language that needs to explictly import a module just to handle the arguments passed to a constructor has some problems. my $obj = Some::Thing->new(-field1 => .., -field2 => ..). Ridiculous. What is wrong with type checking on function parameters. It makes things easier really because you know exactly what is going to be passed to the function. If you want to be able to pass extra things, pass a list or a hash containing these extra things. Foreach, how am i supposed to know if i'm on the last iteration. The only good thing is the regex facilities. Another good reason to hate perl is the arrogance and stupidity of the people writing the texts. "Real perl programmers don't use indexes, they use push and pop." F**k off, sometimes it's useful to use an index. Sometimes I need a for(my $i;$i <= $#array;$i++). Does this mean i'm not a real perl programmer.
One page links to
WhyIHatePerl
:
RecentVisitors